本文概览:介绍lazy-init的全局设置和一个类的两种设置方式;并写了一个测试例子。
1 两种方式
1、方式1-设置全局
| 1 2 3 | <beans default-lazy-init="true">  <!-- no beans will be eagerly pre-instantiated... -->  </beans> | 
2、方式2-设置某一个类
(1)在<bean>中配置lazy属性
| 1 | <bean id= "beanName" lazy-init="true">  </beans> | 
(2) 使用@lazy属性
| 1 2 3 4 5 | @Lazy @Service public class SonService implements InitializingBean {    .... } | 
2 一个实例
对于如下一个bean,
| 1 2 3 4 5 6 7 | public class ExampleBean {     private String name;      public void output(){         System.out.println("对象实例已经存在");     }   } | 
在xml配置<bean>,如下
| 1 2 3 4 5 | <bean id="exampleBean" class="com.companyname.workgroup.apply.module.service.ExampleBean"     lazy-init="true">         <constructor-arg name="name" value="test"/>         <constructor-arg name="learnBeanNameAware" ref="learnBeanNameAware"/> </bean> | 
此时写一个测试类,在使用对象前,如下处加上”exambleBean.output”加上断点,
| 1 2 3 4 5 6 7 | public class Test {     public static void main(String[] args) {         ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");         ExampleBean exapmleBean = (ExampleBean)context.getBean("exampleBean");         exapmleBean.output();     } } | 
进行如下分析,
- 如果此时lazy-init为true,当执行到此断点时,在Context->beanFactory->SingletonObjects中还没有存在这个bean
- 如果此时lazy-init为false或者没有设置(默认为false),当执行到这个断点时,此时在上下文就存在了这个bean,即IOC容器初始化时,就加载了这个对象。
这里还有一个需要注意的地方就是:
“如果一个bean被设置为延迟初始化,而另一个非延迟初始化的singleton bean依赖于它,那么当ApplicationContext提前实例化这个非延迟的singleton bean时,它必须也确保所有上述singleton 依赖的bean被预先初始化,当然也包括设置为延迟实例化的bean”。
3 介绍AbstractApplicationContext#refresh()
一般ApplicationContext的初始化,都会调用AbstractApplicationContext#refresh,
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | public void refresh() throws BeansException, IllegalStateException {         Object var1 = this.startupShutdownMonitor;         synchronized(this.startupShutdownMonitor) {             this.prepareRefresh();             ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();             this.prepareBeanFactory(beanFactory);             try {                 this.postProcessBeanFactory(beanFactory);                 this.invokeBeanFactoryPostProcessors(beanFactory);                 this.registerBeanPostProcessors(beanFactory);                 this.initMessageSource();                 this.initApplicationEventMulticaster();                 this.onRefresh();                 this.registerListeners();                // 用来初始化非lazy-init的bean,加载容器中                 this.finishBeanFactoryInitialization(beanFactory);                 this.finishRefresh();             } catch (BeansException var5) {                 this.destroyBeans();                 this.cancelRefresh(var5);                 throw var5;             }         }     } | 
查看 finitshBeanFactoryInitialization,
| 1 2 3 4 5 | protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {         ..........        // 通过BeanFactory来初始化非lazy-init的对象         beanFactory.preInstantiateSingletons(); } | 
查看preInstanteiateSingletons,发现这个方法是ConfigurableListableBeanFactor的接口,这个接口最终由DefalutListableBeanFactory来实现,如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public void preInstantiateSingletons() throws BeansException { 		List<String> beanNames; 		synchronized (this.beanDefinitionMap) { 			beanNames = new ArrayList<String>(this.beanDefinitionNames); 		} 		for (String beanName : beanNames) { 			.....                        // 创建每一个对象bean 			getBean(beanName); 		        .... 		} } | 
(全文完)






