Browse Source

getBean(name, type) attempts type conversion if necessary (SPR-8480)

3.0.x
Juergen Hoeller 15 years ago
parent
commit
d8a4949faf
  1. 4
      org.springframework.beans/src/main/java/org/springframework/beans/factory/config/ConfigurableBeanFactory.java
  2. 21
      org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java
  3. 17
      org.springframework.context/src/test/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessorTests.java

4
org.springframework.beans/src/main/java/org/springframework/beans/factory/config/ConfigurableBeanFactory.java

@ -1,5 +1,5 @@ @@ -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 @@ -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<? extends PropertyEditor> propertyEditorClass);
void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass);
/**
* Initialize the given PropertyEditorRegistry with the custom editors

21
org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java

@ -1,5 +1,5 @@ @@ -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; @@ -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 @@ -166,6 +167,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
private final ThreadLocal<Object> prototypesCurrentlyInCreation =
new NamedThreadLocal<Object>("Prototype beans currently in creation");
/**
* Create a new AbstractBeanFactory.
*/
@ -189,7 +191,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp @@ -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> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
@ -346,7 +348,16 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp @@ -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 @@ -682,7 +693,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
return this.propertyEditorRegistrars;
}
public void registerCustomEditor(Class requiredType, Class<? extends PropertyEditor> propertyEditorClass) {
public void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> 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 @@ -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();

17
org.springframework.context/src/test/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessorTests.java

@ -1,5 +1,5 @@ @@ -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; @@ -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; @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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() {

Loading…
Cancel
Save