在升级到4.1.4.RELEASE之后,在上下文创建时错误地创建了原型范围的Spring bean

时间:2015-03-04 16:29:50

标签: spring junit

我的测试配置中定义了一个原型范围bean,需要使用ApplicationContext(applicationContext.getBean("my-failing-prototype-bean", myStringParam)创建,因为它有一个需要传递的String参数。

当我在Spring 4.0.4上时,当我运行我的测试时,这工作得很好。当我运行测试类时加载上下文,并且在需要之前不创建原型范围的bean。现在,加载上下文的过程尝试创建我的bean实例失败,因为没有合适的bean匹配我需要手动传递给bean的工厂方法的String参数。

在逐步完成上下文创建过程之后,似乎在尝试自动装配另一个bean时,Spring正在调用DefaultListableBeanFactory.getBeanNamesForType(),调用AbstraceAutowireCapableBeanFactory.getNonSingletonFactoryBeanForTypeCheck()然后调用AbstraceAutowireCapableBeanFactory.createBeanInstance(),因为{{1}返回null。

编辑:在将我的项目提炼到产生问题的示例项目之后,我发现只有在我的测试Spring配置中声明的bean实现AbstraceAutowireCapableBeanFactory.resolveBeforeInstantiation()FactoryBean或{{{ 1}}。它也肯定只发生在测试Spring配置中注入另一个bean时。

感谢您的帮助,如果您有任何更多详细信息,请告诉我们。

GitHub repository for a simple project that reproduces this issue

TestSpringConfig.java

BeanFactoryAware

MyTest.java

BeanClassLoaderAware

堆栈跟踪

@Configuration
public class TestSpringConfig {

    @Inject
    @Named("my-other-bean")
    MyOtherBean myOtherBean;

    @Inject
    private ApplicationContext applicationContext;

    @Bean(name = {"my-failing-prototype-bean"})
    @Scope(BeanDefinition.SCOPE_PROTOTYPE)
    @Profile("test")
    public JndiObjectFactoryBean myFailingPrototypeBean(final String jndiName) {
        JndiObjectFactoryBean jof = new JndiObjectFactoryBean();
        JndiTemplate testJndiTemplate = new JndiTemplate();

        jof.setResourceRef(true);
        jof.setJndiTemplate(testJndiTemplate);
        jof.setJndiName(jndiNameForQueue);

        return jof;
    }

1 个答案:

答案 0 :(得分:1)

据我所知,将bean作为原型并不能阻止它被急切地初始化。尝试在bean中添加@Lazy注释。

@Bean(name = {"my-failing-prototype-bean"})
    @Scope(BeanDefinition.SCOPE_PROTOTYPE)
    @Profile("test")
    @Lazy
    public JndiObjectFactoryBean myFailingPrototypeBean(final String jndiName) {
        JndiObjectFactoryBean jof = new JndiObjectFactoryBean();
        JndiTemplate testJndiTemplate = new JndiTemplate();

        jof.setResourceRef(true);
        jof.setJndiTemplate(testJndiTemplate);
        jof.setJndiName(jndiNameForQueue);

        return jof;
    }