使用lazy-init,加速单元测试速度

来源:互联网 发布:为什么淘宝上苏宁易购 编辑:程序博客网 时间:2024/06/02 04:48
前言:关于lazy-init   

    在 IoC 容器的初始化过程中,主要的工作是对 BeanDefinition 的定位、载入、解析和注册。此时依赖注入并没有发生,依赖注入发生在应用第一次向容器索要 Bean 时。向容器索要Bean是通过getBean的调用来完成的,这个getBean是容器提供Bean服务的最基本的接口。对于容器的初始化也有一种例外情况,就是用户可以通过设置 Bean 的 lazy-init 属性来控制预实例化的过程。这个预实例化在初始化容器时完成 Bean 的依赖注入,毫无疑问,这种容器的使用方式会对容器初始化的性能有一些影响,但却能够提高应用第一次取得 Bean 的性能。因为应用在第一次取得Bean时,依赖注入已经结束了,应用可以取到现成的Bean。

加速单元测试速度
    在做单元测试的时候,其实并不需要一次加载所有的Bean,而Spring中lazy-init默认是false,也就是说在容器初始化的时候,就加载了无数的bean,这大大影响了单元测试的速度。因此在单元测试中可以将lazy-init设置为true,以此来加速单元测试。在配置的过程中需要注意以下几点:
1.在同一个文件中<bean />里面设置的优先级大于<beans />里设置的优先级
<beans />    <bean /> 立即<beans />    <bean lazy-init="true" /> lazy <beans />    <bean lazy-init="false"/> 立即 <beans default-lazy-init="true"/>  <bean /> lazy<beans default-lazy-init="true"/>  <bean lazy-init="true" /> lazy<beans default-lazy-init="true"/>  <bean lazy-init="false" /> 立即<beans default-lazy-init="false"/>  <bean /> 立即<beans default-lazy-init="false"/>  <bean lazy-init="true" /> lazy<beans default-lazy-init="false"/>  <bean lazy-init="false" />   立即


2.如果在一个spring配置文件中引入另外的配置文件,如:<import resource="classpath:beanImport.xml"/>

则以被引入文件(beanImport.xml)中设置的<beans />里的设置为准,与引入文件中的设置无关。

3.不是所有的bean都能设置为default-lazy-init=true,对于scheduler的bean不能使用这种方式,否则所有的scheduler就不管用了。

4.使用下面方法可以是当前项目下所有的bean设置为lazy-init方式

@RunWith(SpringJUnit4ClassRunner.class)
修改为
@RunWith(MyRunner.class)
可以在单元测试期间把所有的bean都做成lazy-init。

package test;import org.junit.runners.model.InitializationError;import org.springframework.beans.factory.config.BeanDefinition;import org.springframework.context.support.GenericApplicationContext;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import org.springframework.test.context.support.GenericXmlContextLoader;public class MyRunner extends SpringJUnit4ClassRunner {    public MyRunner(Class<?> clazz) throws InitializationError {        super(clazz);    }    @Override    protected String getDefaultContextLoaderClassName(Class<?> clazz) {        return MyLoader.class.getName();    }}class MyLoader extends GenericXmlContextLoader {    protected void customizeContext(GenericApplicationContext context) {        String[] names = context.getBeanDefinitionNames();        for (String n : names) {            if(n.startsWith("org.springframework")){                continue;            }            BeanDefinition bd = context.getBeanDefinition(n);            bd.setLazyInit(true);        }            }}




原创粉丝点击