Spring's IOC implementation principle

Source: Internet
Author: User

Some time ago, I wrote an article about the implementation of Spring's AOP framework, and now I'm talking about another big core concept of the IOC principle of spring.
IOC: Control reversal. The official explanation is that the invocation class's dependency on an interface implementation class is injected by a third party to transfer the invocation class's dependency on an interface implementation class.
Here's a practical example to deepen your understanding:

"Script" to select "role" of "actor", we can create a third-party "director" to control the "script", the introduction of "director", "Script" and "actor" will be fully connected. The "director" will have control over the "actor", and the right to reverse refers to the transfer of the "script" to the director.

We re-see the definition of IOC:
IOC: Control reversal. The official explanation is that the dependency of the Calling class ("script") on an Interface implementation class ("actor") is injected by a third party ("director") to transfer the invocation class ("script") to the dependency of an interface implementation class ("actor").

From the injection method, divided into three types
1. Construction Method Injection
2. Attribute Injection
3. Interface Injection

Let's take a look at the specific way we inject it through (script-actor question)
Construction method Injection: By invoking the constructor method of the class, the interface implementation class is passed through the constructor method variable

Call Class (script)

Public class JuBen {  private JueSe Js;  //1:注入角色的具体扮演者  publicJuBen(JueSe Js) {     this.Js=Js;  }       publicvoidDuiBai() {       Js.declare(“我想做一个好人!”);    }

Third party class (director)

Public class Director {  publicvoiddirect() {     //2.指定角色的扮演者     JueSe  new LiuDeHua();     //3.注入具体扮演者到剧本中     new JuBen(Js);     Jb.DuiBai();   }}

attribute injection: It is more flexible and convenient to use the setter method to complete the injection of the required dependency of the calling class
Call Class (script)

Public class JuBen {  private JueSe Js;  //1.属性注入方法  publicvoidsetJueSe(JueSe Js) {     this.Js=Js;  }     publicvoidDuiBai(){     Js.declare(“我想做一个好人!”);                   }}

Third party class (director)

Public class Director {  publicvoiddirect() {     JueSe Js=new LiuDeHua();     JuBen Jb=new JuBen();     //2.调用属性Setter方法注入     Jb.setJueSe(Js);     Jb.DuiBai();}

interface Injection: Extracting all the method of dependency injection of the calling class into an interface, the calling class provides the appropriate injection method by implementing the interface.
1. The injection method that the calling class relies on extracts to the port

Publicinterface ActorArrangable {  void injectJs(JueSe Js);}

2. Invoking the class implementation interface

class JuBen implements ActorArrangable {  private JueSe Js;  //1.实现接口方法  publicvoid injectJs(JueSe Js)       {this.Js = Js; }     publicvoid DuiBai() {     Js.declare(“我想做一个好人!”)    }}

Spring, as a container, describes the dependencies between classes and classes through configuration files or annotations, automating the initialization of classes and the work of dependency injection, which is a configuration file fragment configured for the above instance:

   //1.实现类实例化   <bean id=“Js" class=“LiuDeHua" />   //2.通过ljm-ref建立依赖关系   <bean id=“Juben"   class=“JuBen"  p:ljm-ref=“Js”/></beans>

The previous article on the Java Reflection mechanism, then the relationship between Java reflection and IOC is ...?

In spring, the implementation class, parameter information, and so on, can be configured in its corresponding configuration file, so when the implementation class or parameter information needs to be changed, only the configuration file needs to be modified, and we can also inject other objects needed by an object, which is done in the configuration file.
The implementation of Spring's IOC is based on the reflection mechanism of Java, the Spring factory class will help us to read the configuration file, using reflection mechanism to inject objects, we can get the corresponding object by the name of the bean.

Let me simply implement how IOC can use reflection to read information from a configuration file
1. Need to read configuration information from the configuration file (XML)

 PackageCom.reflect;ImportJava.io.InputStream;ImportJava.lang.reflect.Method;ImportJava.util.HashMap;ImportJava.util.Iterator;ImportJava.util.Map;ImportOrg.dom4j.Attribute;ImportOrg.dom4j.Document;ImportOrg.dom4j.Element;ImportOrg.dom4j.io.SAXReader; Public  class beanfactory {    Privatemap<string, object> beanmap =NewHashmap<string, object> ();/** * The initialization of the Bean factory. * * @param XML XML config file */     Public void Init(String XML) {Try{//1. Creating a Reader object that reads a configuration fileSaxreader reader =NewSaxreader ();//2. Getting the class loader object in the current threadClassLoader ClassLoader = Thread.CurrentThread (). Getcontextclassloader ();//3. Getting the specified XML file from the class directoryInputStream ins = Classloader.getresourceasstream (XML);            Document doc = reader.read (INS);            Element root = Doc.getrootelement (); Element foo;//4. Traversing a bean instance in an XML file             for(Iterator i = Root.elementiterator ("Bean"); I.hasnext ();) {foo = (Element) i.next ();//5. For each bean instance, get the Bean's attribute ID and classAttribute id = foo.attribute ("id"); Attribute CLS = Foo.attribute ("Class");//6. Using the Java reflection mechanism to get the class object through the name of ClassClass bean = Class.forName (Cls.gettext ());//7. Obtaining information for the corresponding classJava.beans.BeanInfo info = java.beans.Introspector.getBeanInfo (bean);//8. Get its property descriptionJava.beans.PropertyDescriptor pd[] = info.getpropertydescriptors ();//9. Create an object and assign a value to the object's properties in the next codeObject obj = bean.newinstance ();//10. Traversing the property properties of the Bean                 for(Iterator ite = Foo.elementiterator ("Property"); Ite.hasnext ();) {element Foo2 = (Element) Ite.next ();//11. Get the property's name attributeAttribute name = Foo2.attribute ("Name"); String value =NULL;//12. Gets the value of the property's child element, value                     for(Iterator ite1 = Foo2.elementiterator ("Value");                     Ite1.hasnext ();)                        {element node = (element) Ite1.next (); Value = Node.gettext (); Break; }//13. Call a set method of an object using the reflection mechanism of Java and set the value in                     for(intK =0; K < Pd.length; k++) {if(Pd[k].getname (). Equalsignorecase (Name.gettext ())) {Method MSet =NULL;                            MSet = Pd[k].getwritemethod ();                        Mset.invoke (obj, value); }                    }                }//14. Placing the object in Beanmap, where key is the ID value and value is the objectBeanmap.put (Id.gettext (), obj); }        }Catch(Exception e)        {System.out.println (e.tostring ()); }    }/** * Gets the Bean object from the bean's ID. * * @param beanname * Bean ID * @return return the corresponding object * *     PublicObjectGetbean(String beanname) {Object obj = Beanmap.get (beanname);returnObj }/** * Test method. * * @param args * *     Public Static void Main(string[] args) {Beanfactory factory =NewBeanfactory (); Factory.init ("Conf/config.xml"); JavaBean JavaBean = (JavaBean) Factory.getbean ("JavaBean"); System.out.println ("Username="+ Javabean.getusername ()); System.out.println ("password="+ Javabean.getpassword ()); }}

2. Configuration files

<?xml version= "1.0" encoding= "UTF-8"?><beans>    <bean id= "JavaBean" class=" Com.jike.spring.chapter03.reflect.JavaBean ">       < property name="UserName">           <value>Jonney</value>       </Property >       < property name="password">           <value>1234567890</value>       </Property >    </Bean></Beans>

3. The corresponding JavaBean

Package com.reflect; Public classJavaBean {PrivateString UserName;PrivateString password; PublicStringGetPassword() {returnPassword } PublicStringGetUserName() {returnUserName; } Public void Setusername(String userName) { This. userName = UserName; } Public void SetPassword(String password) { This. Password = password; }}

Resource Access Tool classes
The class of access resources provided by the JDK does not satisfy the access requirements of various underlying resources, so spring designs a resource interface that provides the application with more powerful access to the underlying resources.

Main methods:
1. Boolean exists ()
2. Boolean IsOpen ()
3. URL GetURL ()
4. File GetFile ()
5. InputStream getInputStream ()

Specific implementation classes:
1. Bytearrayresource
2. Classpathresource
3. Filesystemresource
4. Inputstreamresource
5. Servletcontextresource
6. Urlresource

In order to access different types of resources, you must use the corresponding resource implementation class, which is cumbersome, and spring provides a powerful mechanism for loading resources that can automatically identify different resource types:

Resource type address prefix:
1. Classpath Classpath:com/xxx/bean.xml
2. File File:/com/xxx/bean.xml
3. http://Http://www.xxx.com/bean.xml
4. FTP Ftp://www.xxx.com/bean.xml
5. No prefix com/jike/bean.xml

Ant-Style matching characters:
1.? : Match one of the characters in the file name
2. *: Matches any character in the file name
3. * *: matching multi-layer paths

Examples of ant-style resource paths:
1. Classpath:com/t*st.xml
2. File:d:/conf/*.xml
3. Classpath:com/**/test.xml
4. classpath:org/springframework/*/. xml

Spring defines a set of interfaces for resource loading and provides implementation classes, as follows:

Beanfactory and ApplicationContext

Beanfactory is the core interface of the spring framework, which provides the configuration mechanism of the advanced IOC. Built on Beanfactory, ApplicationContext provides more application-oriented features that provide internationalization support and framework event architecture, making it easier to create practical applications that generally beanfactory as IOC containers, and called ApplicationContext as the application context

Beanfactory

Beanfactory is a class factory that can create and manage objects of various classes, and spring calls these Java objects that are created and managed as beans. In spring, the scope of Java objects is broader. Next we describe the class architecture of beanfactory and the order of loading initialization:

Class Architecture:
1. Xmlbeanfactory
2. Listablebeanfactory
3. Hierarhicalbeanfactory
4. Configurablebeanfactory
5. Autowirecapablebeanfactory
6. Singletonbeanfactory
7. Beandefinitionregistry

Order of initialization:
1. Create a configuration file
2. Loading the configuration file
3. Launch the IOC container
4. Get the Bean instance

ApplicationContext

The ApplicationContext is derived from Beanfactory and provides more functionality for practical applications. In Beanfactory, many functions need to be implemented programmatically, while in ApplicationContext they can be configured in the same way.

Specific implementation classes:
1.ClassPathXmlApplicationContext
2.FileSystemXmlApplicationContext
3.ConfigurableApplicationContext

Expansion interface:
1.ApplicationEventPublisher
2.MessageSource
3.ReaourcePatternResolver
4.LifeCycle

Similar to beanfactory initialization, ApplicationContext initialization is also simple, depending on the configuration file path you can choose different implementation class loading:
Classpathxmlapplicationcontext
Filesystemxmlapplicationcontext
The problem of instantiation of Bean

To load a bean from an XML configuration file using Beanfactory:

importimport org.springframework.core.io.FileSystemResource;   publicclass XmlConfigWithBeanFactory {         publicstaticvoidmain(String[] args) {                new XmlBeanFactory(newFileSystemResource(                                                                                  "build/beans.xml"));      } }

To load a bean from an XML configuration file using ApplicationContext:

publicclass XmlConfigWithApplication{         publicstaticvoid main(String[] args){           new   ClassPathXmlApplicationContext(beans.xml"));             application.getBean("BeanName");       } }

Beanfactory does not instantiate the bean when it initializes the container, and then instantiates the specific bean until the bean is first accessed.
ApplicationContext The bean for instance Singleton when the context is initialized

Spring's IOC implementation principle

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.