diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/ConfigurableBeanFactory.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/ConfigurableBeanFactory.java index a755ea124a..3cb15c5457 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/ConfigurableBeanFactory.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/ConfigurableBeanFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -173,7 +173,7 @@ public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, Single * @param requiredType type of the property * @param propertyEditorClass the {@link PropertyEditor} class to register */ - void registerCustomEditor(Class requiredType, Class propertyEditorClass); + void registerCustomEditor(Class requiredType, Class propertyEditorClass); /** * Initialize the given PropertyEditorRegistry with the custom editors diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java index bab5762070..fa438ea866 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,6 +42,7 @@ import org.springframework.beans.PropertyEditorRegistry; import org.springframework.beans.PropertyEditorRegistrySupport; import org.springframework.beans.SimpleTypeConverter; import org.springframework.beans.TypeConverter; +import org.springframework.beans.TypeMismatchException; import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanCurrentlyInCreationException; import org.springframework.beans.factory.BeanDefinitionStoreException; @@ -166,6 +167,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp private final ThreadLocal prototypesCurrentlyInCreation = new NamedThreadLocal("Prototype beans currently in creation"); + /** * Create a new AbstractBeanFactory. */ @@ -189,7 +191,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); } - + public T getBean(String name, Class requiredType) throws BeansException { return doGetBean(name, requiredType, null, false); } @@ -346,7 +348,16 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp // Check if required type matches the type of the actual bean instance. if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) { - throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); + try { + return getTypeConverter().convertIfNecessary(bean, requiredType); + } + catch (TypeMismatchException ex) { + if (logger.isDebugEnabled()) { + logger.debug("Failed to convert bean '" + name + "' to required type [" + + ClassUtils.getQualifiedName(requiredType) + "]", ex); + } + throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); + } } return (T) bean; } @@ -682,7 +693,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp return this.propertyEditorRegistrars; } - public void registerCustomEditor(Class requiredType, Class propertyEditorClass) { + public void registerCustomEditor(Class requiredType, Class propertyEditorClass) { Assert.notNull(requiredType, "Required type must not be null"); Assert.isAssignable(PropertyEditor.class, propertyEditorClass); this.customEditors.put(requiredType, propertyEditorClass); @@ -1253,7 +1264,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err); } } - + private Class doResolveBeanClass(RootBeanDefinition mbd, Class... typesToMatch) throws ClassNotFoundException { if (!ObjectUtils.isEmpty(typesToMatch)) { ClassLoader tempClassLoader = getTempClassLoader(); diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessorTests.java b/org.springframework.context/src/test/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessorTests.java index b510e257aa..ad78690c4f 100644 --- a/org.springframework.context/src/test/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessorTests.java +++ b/org.springframework.context/src/test/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +22,6 @@ import javax.annotation.PreDestroy; import javax.annotation.Resource; import javax.ejb.EJB; -import static org.junit.Assert.*; import org.junit.Test; import org.springframework.beans.BeansException; @@ -43,6 +42,8 @@ import org.springframework.jndi.support.SimpleJndiBeanFactory; import org.springframework.mock.jndi.ExpectedLookupTemplate; import org.springframework.util.SerializationTestUtils; +import static org.junit.Assert.*; + /** * @author Juergen Hoeller * @author Chris Beams @@ -229,6 +230,7 @@ public class CommonAnnotationBeanPostProcessorTests { bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(ExtendedResourceInjectionBean.class)); bf.registerBeanDefinition("annotatedBean2", new RootBeanDefinition(NamedResourceInjectionBean.class)); + bf.registerBeanDefinition("annotatedBean3", new RootBeanDefinition(ConvertedResourceInjectionBean.class)); TestBean tb = new TestBean(); bf.registerSingleton("testBean", tb); TestBean tb2 = new TestBean(); @@ -238,6 +240,7 @@ public class CommonAnnotationBeanPostProcessorTests { TestBean tb4 = new TestBean(); bf.registerSingleton("testBean4", tb4); NestedTestBean tb6 = new NestedTestBean(); + bf.registerSingleton("value", "5"); bf.registerSingleton("xy", tb6); bf.registerAlias("xy", "testBean9"); @@ -255,6 +258,9 @@ public class CommonAnnotationBeanPostProcessorTests { NamedResourceInjectionBean bean2 = (NamedResourceInjectionBean) bf.getBean("annotatedBean2"); assertSame(tb6, bean2.testBean); + ConvertedResourceInjectionBean bean3 = (ConvertedResourceInjectionBean) bf.getBean("annotatedBean3"); + assertSame(5, bean3.value); + bf.destroySingletons(); assertTrue(bean.destroyCalled); assertTrue(bean.destroy2Called); @@ -591,6 +597,13 @@ public class CommonAnnotationBeanPostProcessorTests { } + private static class ConvertedResourceInjectionBean { + + @Resource(name="value") + private int value; + } + + private static class NullFactory { public static Object create() {