A brief analysis of spring's multiple load bean methods

Source: Internet
Author: User

1 How to define Beans

The common ways to define beans are:

    • by XML, for example:
       <bean id= "Dictionaryrelmap" class  = " Java.util.HashMap "/> 
    • use annotations such as @component on class with annotations such as
       @ Component  public  class   xxxservicer{...}  
    • by means of @bean under the @configuration class, for example
        @Configuration  public  class   xxxconfiguration{@Bean  public   Mybean Mybean () { return    New   Mybean (); }}

Although the three different ways to define beans, the corresponding processing details are different, but from a large logical point of view, are the same. The main process, such as: The problem is to find the way to define the bean, then generate beandefinition to register in the spring context, and spring automatically creates an instance of the bean.

2 beandefinition

Beandefinition is an interface that describes a bean instance, such as Singleton or prototype, what the value of the property is, what the constructor's arguments are, and so on. Simply put, with a beandefinition we can complete a bean instantiation. Beandefinition and its main subclasses:


Here's a brief look at each sub-class:

    • Rootbeandefinition and Childbeandefinition: These 2 beandefinition are relative relations, since spring 2.5 came out, has been replaced by Genericbeandefinition. Because it forces us to be aware of their relationship when writing code.
    • Genericbeandefinition: Hard coding is required compared to rootbeandefinition and childbeandefinition at the time of definition. The genericbeandefinition has the advantage of being able to dynamically set the parent for genericbeandefinition.
    • Annotatedbeandefinition: The name is known to be used to read the definition bean through annotations.
3 defining beans through XML files

Defining a bean through XML is the first way to define a bean in spring. So, how to parse the XML tag into beandefinition (), the entry is in org.springframework.beans.factory.xml.XmlBeanDefinitionReader this class, but the actual work is in org.springframework.beans.factory.xml.BeanDefinitionParserDelegate . The code is a lot, but the actual logic is simple, which is to parse the spring-defined <bean> <property> tags. I've written an article about how to customize the spring label, and then sign in to spring--the portal

4 Loading beans with spring-supported annotations such as @component

If you want to @Component define a bean using such annotations, a precondition is: Yes <context:component-scan/> or no @ComponentScan annotation. But these 2 ways still have a little bit of a difference:

4.1 <context:component-scan/>

Because <context:component-scan/> it is an XML tag, it is parsing the XML, generating the class org.springframework.context.annotation.ComponentScanBeanDefinitionParser , the key code:

@Override PublicBeandefinition Parse (element element, ParserContext ParserContext) {//Get Base-package TagsString Basepackage =Element.getattribute (Base_package_attribute); Basepackage=Parsercontext.getreadercontext (). Getenvironment (). Resolveplaceholders (Basepackage); String[] Basepackages=Stringutils.tokenizetostringarray (Basepackage, configurableapplicationcontext.config_location_delimiters); //the actual processing class is ClasspathbeandefinitionscannerClasspathbeandefinitionscanner scanner =Configurescanner (parsercontext, Element); //Scan all classes under Basepackage, if you have @component and other tags are registered in springSet<beandefinitionholder> beandefinitions =Scanner.doscan (basepackages);    Registercomponents (Parsercontext.getreadercontext (), beandefinitions, Element); return NULL;}
4.2 @ComponentScan

annotation corresponds to the generated class is org.springframework.context.annotation.ComponentScanAnnotationParser actually the last actual work or ClassPathBeanDefinitionScanner this. The ComponentScanAnnotationParser generation of classes is accompanied by @Configuration this annotation process (meaning @ComponentScan must and @Configuration used together). And @Configuration the deal is actually org.springframework.context.annotation.ConfigurationClassPostProcessor . Does it feel a little bit around.
In fact, in the simple case, when the processing @Configuration of the discovery of @ComponentScan annotations, will be generated ComponentScanAnnotationParser to scan @component annotations

4.3 classpathbeandefinitionscanner

As mentioned above, regardless of the annotation or the way of the label, the end will be handed over to ClassPathBeanDefinitionScanner this class to deal with, this class does is 1. Scan all classes under Basepackage, if there are annotations such as @component, read @component related properties, generate ScannedGenericBeanDefinition , register to spring.

5 by @bean Way

Said before the @componentscan is in the @configuration process of a link, since the @bean annotation also must be used with @configuration, then the @bean processing is also in the @configuration, In fact, the final is ConfigurationClassBeanDefinitionReader to this class to deal with, the key code:

Private voidLoadbeandefinitionsforconfigurationclass (ConfigurationClass configclass, Trackedconditionevaluator trackedCon Ditionevaluator) {//If you are defined by @import annotations, you need to register yourself in spring    if(configclass.isimported ()) {Registerbeandefinitionforimportedconfigurationclass (configclass); }    //This is the @bean of the processing method.     for(Beanmethod beanMethod:configClass.getBeanMethods ()) {Loadbeandefinitionsforbeanmethod (Beanmethod); }    //processing @importresource, inside parsing XML is the Xmlbeandefinitionreader of parsing XML mentioned aboveloadbeandefinitionsfromimportedresources (Configclass.getimportedresources ()); Loadbeandefinitionsfromregistrars (Configclass.getimportbeandefinitionregistrars ());}
6 instantiation of the Beandefinition

The previous section said how to convert different definitions of beans to beandefinition to join spring (to be sure to remain in the Beanfactory Beandefinitionmap), The instance is in the final phase of ApplicationContext, and the key code is in Defaultlistablebeanfactory

@Override Public voidPreinstantiatesingletons ()throwsbeansexception { for(String beanname:beannames) {rootbeandefinition bd=getmergedlocalbeandefinition (beanname); if(!bd.isabstract () && Bd.issingleton () &&!Bd.islazyinit ()) {            if(Isfactorybean (beanname)) {FinalFactorybean<?> factory = (factorybean<?>) Getbean (Factory_bean_prefix +beanname); BooleanIseagerinit; if(System.getsecuritymanager ()! =NULL&& FactoryinstanceofSmartfactorybean) {Iseagerinit= Accesscontroller.doprivileged (NewPrivilegedaction<boolean>() {@Override PublicBoolean Run () {return((smartfactorybean<?>). Factory). Iseagerinit ();                }}, Getaccesscontrolcontext ()); }                Else{iseagerinit= (FactoryinstanceofSmartfactorybean &&((Smartfactorybean<?>) factory). Iseagerinit ()); }                if(iseagerinit) {Getbean (beanname); }            }            Else{Getbean (beanname); }        }    }
}

By Getbean the last last instance of the code, in Abstractautowirecapablebeanfactory

protectedObject Initializebean (FinalString Beanname,FinalObject Bean, rootbeandefinition mbd) {    //Handling Xxaware Interfaces    if(System.getsecuritymanager ()! =NULL) {accesscontroller.doprivileged (NewPrivilegedaction<object>() {@Override PublicObject Run () {invokeawaremethods (beanname, Bean); return NULL;    }}, Getaccesscontrolcontext ()); }    Else{invokeawaremethods (beanname, Bean); } Object Wrappedbean=Bean; if(mbd = =NULL|| !mbd.issynthetic ()) {        //Call Beanpostprocessors#postprocessbeforeinitializationWrappedbean =applybeanpostprocessorsbeforeinitialization (Wrappedbean, beanname); }    Try {       //Initialize, first determine whether it is Initializingbean,invokeinitmethods (Beanname, Wrappedbean, mbd); }    Catch(Throwable ex) {Throw Newbeancreationexception ((mbd!=NULL? Mbd.getresourcedescription ():NULL), Beanname,"Invocation of Init method failed", ex); }    if(mbd = =NULL|| !mbd.issynthetic ()) {        //Call Beanpostprocessors#postprocessafterinitializationWrappedbean =applybeanpostprocessorsafterinitialization (Wrappedbean, beanname); }    returnWrappedbean;}

As you can see from the above initialization, Initializebean and Beanpostprocessors call order
7 Summary

Based on the analysis, the spring load bean is the same as the big idea, first read the relevant information to generate Beandefinition, and then initialize the bean through beandefinition. If you know the above routines, you can clearly see how to customize XML tags or custom annotations to inject beans into spring.

A brief analysis of spring's multiple load bean methods

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.