默认情况下,bean都是单例的(除非设置了scope属性),单例bean会在容器启动时实例化(如果将scope设置为prototype,则在请求使用时才会实例化)
这样做是有好处的,可以尽早(部署阶段)发现配置或环境错误。
如果不想让bean在Spring初始化时就被创建,则可以使用<bean/>
标签的lazy-init
属性来关闭这个选项。
<bean id="lazy" class="com.something.ExpensiveToCreateBean" lazy-init="true"/>
默认情况下,lazy-init="false"
如果bean被设置了延迟初始化,bean在第一次被请求时创建实例。
延迟初始化不会破坏“单例”特性
默认情况下,单例bean在容器的初始化阶段实例化。如果开启延迟初始化,在第一次请求时实例化,仍然保留单例特性
package SpringTest.lazyInitialized;
public class TestLazyInit {
public TestLazyInit() {
System.out.println("bean被创建");
}
}
<bean id="lazyBean" class="SpringTest.lazyInitialized.TestLazyInit" lazy-init="true"></bean>
初始化容器后,两次请求这个bean,并判断它们是否是同一个bean:
System.out.println(context.getBean("lazyBean") == context.getBean("lazyBean"));
运行结果:
延迟初始化的bean在容器初始化阶段被请求
package SpringTest.lazyInitialized;
public class TestLazyInit {
private TestLazyInit pro;
public TestLazyInit(String beanName, TestLazyInit pro) {
this.pro = pro;
System.out.println(beanName + "被创建");
}
}
配置元数据:
<bean id="lazyBean" class="SpringTest.lazyInitialized.TestLazyInit" lazy-init="true">
<constructor-arg value="lazyBean"></constructor-arg>
<constructor-arg><null/></constructor-arg>
</bean>
<bean id="notLazyBean" class="SpringTest.lazyInitialized.TestLazyInit">
<constructor-arg value="notLazyBean"></constructor-arg>
<constructor-arg ref="lazyBean"></constructor-arg>
</bean>
初始化容器时的运行结果:
延迟初始化bean被注入到非延迟初始化的bean,当非延迟初始化的bean实例化时,需要进行依赖注入,第一次请求便发生在这里,所以在Spring初始化的阶段延迟初始化bean被创建