Spring Learning Note--spring Dependency Injection principle analysis

Source: Internet
Author: User
Tags xml attribute xpath

We know that spring's dependency injection has four ways, namely Get/set method injection, constructor injection, static factory method injection, instance factory method injection
Let's start by analyzing these kinds of injection methods.
1. Get/set Method Injection

publicclass SpringAction {        //注入对象springDao    private SpringDao springDao;        //一定要写被注入对象的set方法        publicvoidsetSpringDao(SpringDao springDao) {        this.springDao = springDao;    }        publicvoidok(){        springDao.ok();    }}

The configuration file is as follows:

<!--configuration Bean, which is configured with spring management    <Bean name= "springaction" class=" Com.bless.springdemo.action.SpringAction ">        <!--(1) Dependency injection, configuring the corresponding property in the current class --        < property name="Springdao" ref="Springdao"></Property >    </Bean><Bean name= "Springdao" class=" Com.bless.springdemo.dao.impl.SpringDaoImpl "></Bean>

2. Constructor injection

publicclass SpringAction {    //注入对象springDao    private SpringDao springDao;    private User user;    publicSpringAction(SpringDao springDao,User user){        this.springDao = springDao;        this.user = user;        System.out.println("构造方法调用springDao和user");    }        publicvoidsave(){        springDao.save(user);    }}

In the same unused form in the XML file, the tag is used, and the ref attribute also points to the Name property of the other label:

<!--configuration Bean, which is configured with spring management    <Bean name= "springaction" class=" Com.bless.springdemo.action.SpringAction ">        <!--(2) to create a constructor injection, if the main class has a constructor that has parameters, you need to add this configuration --        <constructor-arg ref="Springdao"></constructor-arg>        <constructor-arg ref="user"></constructor-arg>    </Bean>        <Bean name= "Springdao" class=" Com.bless.springdemo.dao.impl.SpringDaoImpl "></Bean>        <Bean name="User" class="Com.bless.springdemo.vo.User" ></Bean>

In the same unused form in the XML file, the tag is used, and the ref attribute also points to the Name property of the other label:
To solve the uncertainty of the constructor method parameters, you may encounter the constructor method the two parameters passed in are the same type, in order to distinguish which one should be assigned the corresponding value, you need to do some small processing:

<Bean name= "springaction" class=" Com.bless.springdemo.action.SpringAction ">          <constructor-arg Index="0" ref="Springdao"></constructor-arg>          <constructor-arg Index="1" ref="user"></constructor-arg>  </Bean>  

The other is to set the parameter type:

<constructor-arg type="java.lang.String" ref=""/>  

3, Static factory method injection
By calling the static factory method to get the objects you need, in order for spring to manage all the objects, we cannot get the objects directly through the class name plus method, so we can get rid of spring's management, but instead take the form of spring injection.

Packagecom. Bless. Springdemo. Factory;Importcom. Bless. Springdemo. DAO. Factorydao;Importcom. Bless. Springdemo. DAO. Impl. Factorydaoimpl;Importcom. Bless. Springdemo. DAO. Impl. Staticfacotrydaoimpl;public class Daofactory {//static factory public static final Factorydao Getstaticfactorydaoimpl () {return new STATICF Acotrydaoimpl ();}}

Also look at the key class, where I need to inject a Factorydao object, which looks exactly like the first injection, but looking at the subsequent XML will find a big difference:

publicclass SpringAction {        //注入对象    private FactoryDao staticFactoryDao;    publicvoidstaticFactoryOk(){        staticFactoryDao.saveFactory();    }    //注入对象的set方法    publicvoidsetStaticFactoryDao(FactoryDao staticFactoryDao) {        this.staticFactoryDao = staticFactoryDao;    }}

The configuration file is as follows:

<!--configuration Bean, which is configured with spring management    <Bean name= "springaction" class=" Com.bless.springdemo.action.SpringAction " >        <!--(3) Use the static factory method to inject the object, corresponding to the following configuration file (3) --        < property name="Staticfactorydao" ref="Staticfactorydao" ></Property >                </Property >    </Bean>    <!--(3) The way to get objects here is to get the static method from the factory class--    <Bean name= "Staticfactorydao" class=" Com.bless.springdemo.factory.DaoFactory " factory-method=" Getstaticfactorydaoimpl "> </Bean>

4. Example Factory method injection
The instance factory means that the method that gets the object instance is not static, so you need to first new factory class and then call the normal instance method:

public   Class  Daofactory {//instance factory  public  Factory Dao getfactorydaoimpl  () {return  new  Factorydaoimpl (); }}
publicclass SpringAction {    //注入对象    private FactoryDao factoryDao;    publicvoidfactoryOk(){        factoryDao.saveFactory();    }    publicvoidsetFactoryDao(FactoryDao factoryDao) {        this.factoryDao = factoryDao;    }}
<!--configuration Bean, which is configured with spring management    <Bean name= "springaction" class=" Com.bless.springdemo.action.SpringAction ">        <!--(4) Use the method of the instance factory to inject the object, corresponding to the following configuration file (4) --        < property name="Factorydao" ref="Factorydao"></Property >    </Bean>    <!--(4) The way to get an object here is to get the instance method from the factory class--    <Bean name= "daofactory" class=" Com.bless.springdemo.factory.DaoFactory "></Bean>    <Bean name="Factorydao" factory-bean="Daofactory" Factory-method="Getfactorydaoimpl"></Bean>

For the 1th, 2 kinds of We use more, the latter two may be more unfamiliar.
Let's analyze how spring completes dependency injection. If we go to see Spring's source code may involve a considerable number of classes and interfaces, not easy to grasp, here I use their own code and way to help us spring dependency injection process.
When we start the spring container, he performs the following procedures:
1. Load XML configuration file (ReadXML (String filename)) in spring This is done by the ApplicationContext class
This step parses the XML attribute and stores the bean's attributes in the Beandefinition class
The code is as follows:

/** * Read XML config file * @param filename */    Private void ReadXML(String filename) {Saxreader Saxreader =NewSaxreader (); Document document=NULL;Try{URL Xmlpath = This. GetClass (). getClassLoader (). getresource (filename);             Document = Saxreader.read (Xmlpath); Map<string,string> Nsmap =NewHashmap<string,string> (); Nsmap.put ("NS","Http://www.springframework.org/schema/beans");//Join a namespaceXPath xsub = Document.createxpath ("//ns:beans/ns:bean");//Create Beans/bean query pathXsub.setnamespaceuris (NSMAP);//Set namespacelist<element> beans = xsub.selectnodes (document);//Get all bean nodes under document              for(Element Element:beans) {String id = element.attributevalue ("id");//Get id attribute valueString clazz = Element.attributevalue ("Class");//Get class attribute valueBeandefinition Beandefine =NewBeandefinition (ID, clazz); XPath propertysub = Element.createxpath ("Ns:property"); Propertysub.setnamespaceuris (NSMAP);//Set namespacelist<element> propertys = Propertysub.selectnodes (Element); for(Element Property:propertys) {String propertyname = Property.attributevalue ("Name"); String PropertyRef = Property.attributevalue ("ref"); PropertyDefinition propertydefinition =NewPropertyDefinition (PropertyName, PropertyRef);                Beandefine.getpropertys (). Add (PropertyDefinition);             } beandefines.add (Beandefine); }             }Catch(Exception e)            {E.printstacktrace (); }    }

2. Instance of Bean
In the configuration file, put the Bean's ID key,beandefinition as value into the map

/**     * 完成bean的实例化     */    privatevoidinstanceBeans() {        for(BeanDefinition beanDefinition : beanDefines){            try {                if(beanDefinition.getClassName()!=null && !"".equals(beanDefinition.getClassName().trim()))                    sigletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClassName()).newInstance());            catch (Exception e) {                e.printStackTrace();            }        }    }

3, inject the input value for the bean, complete the dependency injection

/** * Inject values for the properties of the Bean object * /    Private void Injectobject() { for(Beandefinition beandefinition:beandefines) {Object bean = Sigletons.get (Beandefinition.getid ());if(bean!=NULL){Try{propertydescriptor[] ps = Introspector.getbeaninfo (Bean.getclass ()). Getpropertydescriptors (); for(PropertyDefinition PropertyDefinition:beanDefinition.getPropertys ()) { for(PropertyDescriptor Properdesc:ps) {if(Propertydefinition.getname (). Equals (Properdesc.getname ())) {Method setter = Properdesc.getwritemethod ();//Get property setter method, Private                                if(setter!=NULL{Object value = Sigletons.get (Propertydefinition.getref ()); Setter.setaccessible (true); Setter.invoke (bean, value);//Inject the reference object into the property} Break; }                        }                    }                }Catch(Exception e) {                }            }        }    }

In fact, Spring relies on the injection process is so simple, and then a variety of details, such as lazy loading, singleton, such as the additional processing.

Spring Learning Note--spring Dependency Injection principle analysis

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.