Spring's Lazy-init autowired depends-on

Source: Internet
Author: User

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:

    1. Finishbeanfactoryinitialization (beanfactory);

Tracking down can find the real read Lazy-init property for lazy loading related processing place

    1. 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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.