本文概览:介绍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); .... } } |
(全文完)