为什么在junit测试期间将bean多次初始化?

时间:2018-08-24 07:26:25

标签: java spring junit

能否请您帮助我了解为什么会发生以下情况? 我有以下bean:

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class TestBean implements BeanPostProcessor {
    public void init() {
        System.out.println("Initialized!");
    }

    public void destroy() {
        System.out.println("Destroyed!");
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization");
        return null;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization");
        return null;
    }
}

具有以下配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean class="TestBean" init-method="init" destroy-method="destroy"/>
</beans>

和以下junit测试:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:beans1.xml"})
public class TestBeanTest {

    @Autowired
    private TestBean collectionBean;

    @Test
    public void testCollectionBean() {
    }
}

现在,令我惊讶的是,如果我运行该单元测试,“ postProcessBeforeInitialization”和“ postProcessAfterInitialization”将分别打印5次。是什么原因?在bean初始化期间,它们不应该只打印1次吗? 预先谢谢你!

2 个答案:

答案 0 :(得分:4)

回顾我的评论:

TestBean bean后处理器postProcessBeforeInitialization方法进行了少许更改:

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    System.out.println("postProcessBeforeInitialization " + beanName);
    return null;
}

可能的最小Spring依赖性:org.springframework:spring-context:5.0.2.RELEASE

您的代码输出为:

postProcessBeforeInitialization org.springframework.context.event.internalEventListenerProcessor
postProcessBeforeInitialization org.springframework.context.event.internalEventListenerFactory
postProcessBeforeInitialization TestBeanTest

结论:后处理器只对bean进行一次后处理,其余都是Spring自己的bean。您得到5而我仅得到3的事实是我们正在使用的不同依赖项集。

另外,请注意,TestBean甚至不被考虑(打印),因为它不是bean,而是bean后处理器。

答案 1 :(得分:1)

我认为文档和方法签名应该可以帮助您理解问题。

  

工厂挂钩,允许自定义修改新bean   实例,例如检查标记界面或将其包装   代理

我建议您也打印出bean名称。这将向您显示诸如EventlistnerFactories之类的bean和其他以编程方式注入您的bean的工厂方法。因此,在注入之前,将针对每个这些bean调用此方法,从而使您有机会在需要时代理或包装bean。