Closed
Description
I'm trying upgrade spring from 5.1.4.RELEASE to 5.2.0.RC1, some tests with @Autowired
fails caused by NoSuchBeanDefinitionException
, I found there is a regression of BeanFactory::getBean(Class<T> requiredType)
. and use
@Bean
public MyServiceFactoryBean MyService() {
return new MyServiceFactoryBean();
}
instead of
@Bean
public BeanDefinitionRegistryPostProcessor beanDefinitionRegistryPostProcessor() {
return new MyBeanDefinitionRegistryPostProcessor();
}
will success.
here is the full test case
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = MyTest.MyConfiguration.class)
public class MyTest {
@Autowired
DefaultListableBeanFactory beanFactory;
@Autowired
MyService myService;
// @Autowired
// autowire will fail
MyServiceFactoryBean MyFactoryBean;
@Test
public void testGetBean() throws Exception {
String beanName = MyService.class.getSimpleName();
assertThat(beanFactory.getBean(beanName), is(myService));
assertThat(beanFactory.getBean("&" + beanName), notNullValue());
assertThat(beanFactory.getBeansOfType(FactoryBean.class).size(), is(1)); // is(0)
assertThat(beanFactory.getBeansOfType(MyServiceFactoryBean.class).size(), is(1)); // is(0)
assertThat(beanFactory.getBean(MyServiceFactoryBean.class), notNullValue()); // NoSuchBeanDefinitionException
}
static class MyConfiguration {
@Bean
public BeanDefinitionRegistryPostProcessor beanDefinitionRegistryPostProcessor() {
return new MyBeanDefinitionRegistryPostProcessor();
}
}
public interface MyService {
}
public static class MyServiceFactoryBean implements FactoryBean<MyService> {
@Override
public MyService getObject() throws Exception {
return new MyService() {
};
}
@Override
public Class<?> getObjectType() {
return MyService.class;
}
}
public static class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
RootBeanDefinition beanDefinition = new RootBeanDefinition(MyServiceFactoryBean.class.getCanonicalName());
beanDefinition.setPrimary(true);
beanDefinition.setTargetType(MyService.class);
beanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_NO);
beanDefinition.setAttribute(getClass().getName(), true);
registry.registerBeanDefinition(MyService.class.getSimpleName(), beanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory bf) throws BeansException {
}
}
}