1 Lazy-init
Lazy-init is the meaning of deferred initialization.
Containers in spring are created and configured for all singleton beans as early as possible, so when the container starts, it configures and creates a singleton bean. By default, Beans's lazy-init is not configured, which is equivalent to:
Default-lazy-init= "false"
The Bean's lazy-init is inherited from the beans configuration by default. In other words, no lazy-init is configured: Lazy-init = False
The advantage of this is that the configuration errors or environmental issues can be immediately exposed when the program is just running. Of course, the downside is that when you start up, because you want to initialize all of the singleton beans, the overhead is huge and the startup process is slow.
If you do not want a singleton bean to be instantiated in advance, you can set the lazy-initialized lazy load to initialize only when the first request is initiated, rather than when the container is started.
If a non-deferred singleton Bean relies on a bean that is tagged with lazy-init, the bean that marks the Lazy-init is also created when the container is started (delayed initialization is invalidated).
When a bean that is set to defer loading is injected into a singleton bean without delay, it means that it is not delayed loading.
You can see the code for all of the registered beans , the This. beandefinitionnames, for each bean will make the following judgment, if it is set up will perform dependency injection:
The initialization of the container is performed in the Abstractapplicationcontext Refresh () method, and the following code handles the Lazy-init:
- Finishbeanfactoryinitialization (beanfactory);
Tracking down can find the real read Lazy-init property for lazy loading related processing place
- if (!bd.isabstract () && Bd.issingleton () &&!bd.islazyinit ())
As can be seen, only a single bean can complete the dependency injection when the container is initialized, when the Lazy-init property is not configured (the default) or configured to False, the above if will be set up, of course, the default does not configure the abstract property, So it is also false by default. If set, the Getbean is executed for dependency injection, so that the bean is instantiated during container initialization, and when the bean is actually requested, it is only read from the cache.
If the Lazy-init property is configured to True, then lazy loading is done, so that no dependency injection occurs during container initialization, and the bean is instantiated only when the first Getbean.
2 Lazy-init & Depends-on
<!--Remove the attribute injection configuration information for the boss Bean--<bean id="boss" class="Com.baobaotao.Boss"lazy-init="true"/> <!--depends-on test, after removing Lazy-init configuration, which is set to Fasle, then--<bean id="Mans" class="Com.baobaotao.Man"depends-on="boss"lazy-init="true"/>
Depends-on is a sequence of initialization, which is not the same as direct property dependency (such as man owning a boss property). But the performance is similar.
Specifically, in the above example, if the man is deferred initialization, it does not matter if the boss is delaying initialization. However, if Mans is initialized immediately, the boss is also immediately required to initialize, even if the boss sets lazy-init= "true". If the boss cannot autowire certain properties, then the container throws an exception, and man can no longer complete the initialization!
Why is that? Observation source is visible:
Abstractbeanfactory.dogetbean Method:
Final Rootbeandefinition Ex1 = This. Getmergedlocalbeandefinition (Beanname); This. Checkmergedbeandefinition (Ex1, beanname, args); String[] DependsOn=Ex1.getdependson (); String[] ScopeName; if(DependsOn! =NULL) {//This starts processing the other beans on which the bean depends scopeName=DependsOn; intScope =dependson.length; for(intEX2 =0; EX2 < scope; ++ex2) {String dep=Scopename[ex2]; if( This. Isdependent (Beanname, DEP)) { Throw NewBeancreationexception (Ex1.getresourcedescription (), Beanname,"Circular depends-on relationship between \ '"+ Beanname +"\ ' and \ '"+ dep +"\ '"); } This. Registerdependentbean (DEP, Beanname); This. Getbean (DEP); } }
In addition, from the exception stack, it is visible that there are repeated calls between the Getbean and Dogetbean methods, and this is exactly what spring is doing with depends-on dependencies:
At Org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton ( Defaultsingletonbeanregistry.java: the) at Org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean (Abstractbeanfactory.java:302) at Org.springframework.beans.factory.support.AbstractBeanFactory.getBean (Abstractbeanfactory.java:197) at Org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean (Abstractbeanfactory.java:296Here there are repeated calls at Org.springframework.beans.factory.support.AbstractBeanFactory.getBean ( Abstractbeanfactory.java:197) at Org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons ( Defaultlistablebeanfactory.java:759)
3 Lazy-init & autowired Notes
Lazy-init and autowired actually have no definite relationship. Autowired is responsible for injection, while Lazy-init relates to initialization. The only point of the relationship is that the bean injected by autowired must be a bean that has already been initialized successfully. In other words, autowired is equivalent to calling Getbean, so whatever lazy-init is set up, the dependent bean that is required by Autowire must be initialized.
If a bean needs autowire to inject another failed bean, however, the bean does not require immediate initialization, then this autowire potential error is not exposed. That is, a possible exception is postponed.
Reference:
Http://blog.csdn.net/qq30211478/article/details/77847677?locationNum=4&fps=1
Configuration of Lazy-init attribute of http://blog.csdn.net/u011734144/article/details/72632327?locationNum=8&fps=1:Spring source code analysis
Lazy-init has 3 options, True, False, default
Spring's Lazy-init autowired depends-on