Spring Source Analysis-core IOC container principle __spring

Source: Internet
Author: User
Tags aliases assert readable
about IOC

It is believed that the IOC and the Bean are the most commonly heard two nouns when learning spring, and that the frequency with which the IOC is learning spring must have its reasons. If we make a metaphor, the bean is the main actor in spring, then the IOC is the stage where the protagonist performs, without the IOC as the Bean's bearer, then the bean will not shine in programming. As an important member of the spring core component, understanding its internal implementation is quite helpful for us to program and pry into the inner spring, and to analyze how the IOC is actually implemented from the source perspective. Interface Design

First, we understand the design framework of the IOC container as a whole through an interface design diagram.
Source Analysis beanfacory

Through the interface design above, we can see that the most basic IOC container interface in spring is beanfactory, which defines some of the most basic operations and functions as an IOC container, and looks at its source code:

Package org.springframework.beans.factory;
Import org.springframework.beans.BeansException;

Import Org.springframework.core.ResolvableType; /** * Beanfactory as the most original and most important IOC container, its main function is to provide support for dependency injection (DI), beanfactory and related interfaces. This is defined as a series of interface methods, with this series of beanfactory interfaces, it is possible to use different bean retrieval methods to easily get the required beans from the IOC container, thus ignoring the implementation of the specific IOC container, which represents the most basic capacity
 Entrance of the device. * @author Rod Johnson * @author Juergen Hoeller * @author Chris beams * @since April 2001/public interface is
     anfactory {/** * "&" is used to refer to an instance, or to separate it from the bean area produced by the factory, that is, if a factorybean is named a, then &a will get that factory * * Factorybean and Beanfactory are the most frequently used classes in spring, and they are similar in spelling. One is factory, the IOC container or object factory; A * is a bean. In spring, all of the beans are managed by beanfactory (the IOC container).
     But for Factorybean, the bean is not a simple be *, but rather a factory bean that produces or modifies object generation, and its implementation is similar to the factory pattern and decorator pattern in design mode.

    * * String Factory_bean_prefix = "&"; /** * Five different forms of Getbean method, get instance * @param name Retrieve bean name * @return Object (<T> T) Instance Object * @throws Bean SexceptIon if the bean cannot obtain the */Object Getbean (String name) throws Beansexception;
    <T> T Getbean (String name, Class<t> requiredtype) throws beansexception;
    <T> T Getbean (class<t> requiredtype) throws beansexception;
    Object Getbean (String name, Object ... args) throws beansexception;

    <T> T Getbean (class<t> requiredtype, Object ... args) throws beansexception;
     /** * Lets the user determine whether the container contains a bean with the specified name.

    * @param the name of the bean used for the name search * @return Boolean contains the * * Boolean Containsbean (String name);
     /** * Queries whether the bean of the specified name is a singleton type bean.
     * For the Singleton property, you can specify it in Beandefinition. * @param the name of the bean used for the name search * @return Boolean whether the package is singleton * @throws Nosuchbeandefinitionexception did not find the bean *

    /boolean Issingleton (String name) throws Nosuchbeandefinitionexception;
     /** * Query whether the bean of the specified name is of type prototype.
     * As with the Singleton property, it can be specified in Beandefinition.
 * @param the name of the bean used for the name search * @return Boolean whether the package is prototype    * @throws Nosuchbeandefinitionexception did not find the Bean/boolean isprototype (String name) throws Nosuchbeandefinit

    Ionexception;
     /** * Queries whether the class type of the bean with the specified name is a specific class type. * @param typetomatch Match Type * @return Boolean is a specific type * @throws nosuchbeandefinition of the bean name used for the name search Exception did not find Bean/boolean istypematch (String name, Resolvabletype typetomatch) throws Nosuchbeandefinitionexc
    Eption;

    Boolean Istypematch (String name, class<?> typetomatch) throws nosuchbeandefinitionexception;
     /** * Queries the class type of the bean that specifies the name.
     * @param the name of the bean used for the name search * @return specified bean or null (no appropriate bean found) * @throws Nosuchbeandefinitionexception did not find the bean

    */class<?> GetType (String name) throws Nosuchbeandefinitionexception;
     /** * Query for all aliases of the named Bean, which are defined in Beandefinition * @param name of the bean used in the name search @return all aliases of the bean with the specified name or an empty array
*/string[] getaliases (String name);
 }

Through the above interface, we see that the most basic behavior of the IOC container is defined in beanfactory, without concern for how the bean is defined and loaded. If we want to know the process of a factory specific production object, we need to see the implementation class of this interface, there are many subclasses that implement this interface in spring, let's look at the Code of the common implementation class xmlbeanfacotry. Xmlbeanfactory

Package org.springframework.beans.factory.xml;
Import org.springframework.beans.BeansException;
Import Org.springframework.beans.factory.BeanFactory;
Import Org.springframework.beans.factory.support.DefaultListableBeanFactory;

Import Org.springframework.core.io.Resource; /** * Xmlbeanfactory is the simplest implementation class of Beanfactory * * Xmlbeanfactory is built on the basis of defaultlistablebeanfactory this basic container, Additional features such as * XML read are implemented on the basis of this basic container.
 Xmlbeanfactory used Defaultlistablebeanfactory as the basic class, Defaultlistablebeanfactory is a very heavy * to the IOC implementation, will be highlighted in the next chapter. * @author Rod Johnson * @author Juergen Hoeller * @author Chris beams * @since April 2001/public class Xmlbea Nfactory extends Defaultlistablebeanfactory {private final Xmlbeandefinitionreader reader = new Xmlbeandefinitionrea

    Der (this); /** * Based on a given source, create a xmlbeanfactory * @param resource The abstraction of the external resources in spring, most commonly the abstraction of the file, especially the XML file.
     and resource usually * is the bean definition that holds the spring user, such as Applicationcontext.xml is abstracted as resource when it is loaded. * @throws BeansexceptiError in loading or parsing/public xmlbeanfactory (Resource Resource) throws Beansexception {This (Resource, null); /** * Creates a xmlbeanfactory * @param resource The abstraction of the external resource in spring from the given source and beanfactory, most commonly the abstraction of the file, especially the XML file.
     and resource usually * is the bean definition that holds the spring user, such as Applicationcontext.xml is abstracted as resource when it is loaded. * @param parentbeanfactory the beanfactory * @throws beansexception Loading or parsing error/public xmlbeanfactory (Reso
        Urce resource, Beanfactory parentbeanfactory) throws beansexception {super (parentbeanfactory);
    This.reader.loadBeanDefinitions (Resource);
 }
}

We can see that we need a Resource object to construct the Xmlbeanfactory object, what is this Resource?

Simply speaking, the resource interface is an abstraction that provides a stronger access to the underlying resource capabilities, which is the most basic interface for spring access resources.

By Xmlbeanfactory we can also roughly guess that the resource object for the class is an XML file stream. So, now that we know the usage of this beanfactory simple implementation class, and we know the parameters of constructing this object, let's start by practicing creating an original IOC container. using Xmlbeanfactory to achieve the most original IOC container preparatory work

1. Entity class User.java

public class user{
    private String name;
    private int age;

    Getter ();
    Setter ();
}

2. xml resource file Beans.xml

    <bean id= "user1" Name= "user1" class= "Com.yanxiao.ioc.User" >
        <property name= "name" value= "Yanxiao" > </property>
        <property name= "age" value= "></property>
    </bean>
use of the original IOC container
Package com.yanxiao.ioc;

Import org.springframework.beans.factory.BeanFactory;
Import org.springframework.beans.factory.xml.XmlBeanFactory;
Import Org.springframework.core.io.ClassPathResource;

/**
 * Created by Yanxiao on 2016/7/28.
 *
/@SuppressWarnings ("deprecation") public
class Mysimplebeanfactory {public
    static void Main (string[) args) {
        Classpathresource resource = new Classpathresource ("Meta-inf/beans.xml");
        Beanfactory beanfactory = new Xmlbeanfactory (resource);
        User user = Beanfactory.getbean ("user1", User.class);
        System.out.println (User.getname () + ":" +user.getage ());
    }
}
track the code flow above

Using Single-step debugging to understand the main internal call flow of the above code, there is no procedure for tracking the Getbean () method, which is followed by the parsing process of the bean, which we'll talk about later.

Call Order class name Method Name
1 Xmlbeanfactory Construction Method (Resource)
2 Defaultlistablebeanfactory Construction Method (Beanfactory)
3 Abstractautowirecapablebeanfactory Construction Method (Beanfactory)
4 Abstractautowirecapablebeanfactory Setparentfactory (Beanfactory)
5 Xmlbeandefinitionreader Loadbeandefinitions (Resource)
6 Abstractbeandefinitionreader Getresourceloader ()

Through the above process, we can simply summarize the steps to use the IOC container as follows:

    1. Create an abstract resource for the IOC configuration file, which contains the definition information of the Beandefinition
    2. Create a beanfactory, where Defaultlistablebeanfactory 3 is used
    . Creates a beandefinition reader, where Xmlbeandefinitionreader is used to load the Beandefinition 4 in the form of an XML file
    . And then the resource that is positioned above, Configured with a callback to Beanfactory
    5. Read the configuration information from the location of a good resource, and the specific parsing process is completed by Xmlbeandefinitionreader
    6. After you complete the load and register bean definitions, The required IOC container is initially established.

After we have an understanding of this internal process, we can apply it in practice, and the Mysimplebeanfactory code we wrote earlier can be changed to the following form:

public static void Main (string[] args) {
        Classpathresource resource = new Classpathresource ("Meta-inf/beans.xml"); C8/>defaultlistablebeanfactory factory = new Defaultlistablebeanfactory ();
        Xmlbeandefinitionreader reader = new Xmlbeandefinitionreader (factory);
        Reader.loadbeandefinitions (Resource);
        User user = Factory.getbean ("user", User.class);
        System.out.println (User.getname () + ":" +user.getage ());
    }

The role of the two is equivalent.

Now that we have a general understanding of the IOC, some of the key points are analyzed in detail below. First of all, from the Classpathresource object we created in our first step, we're going back to the resource in spring. Resource Interface System

In the above article we also briefly mentioned the role of the Resource interface, in fact, Spring uses its own abstract structure of the entire framework used in the unified packaging of resources, the reason for encapsulating this interface in fact, we can generally think of, We have encountered in the programming of a variety of resource file types, such as file, InputStream, Urlresource, Contextresource, etc., in the face of so many resource types within the framework of the design of a mature and reasonable resource packaging system, There is no doubt that the implementation of the framework and the developer's programming has caused a lot of complexity. The encapsulation and inheritance features of object-oriented programming can be very useful in spring, and there is time to take a moment to realize that the Spring framework design system is a great benefit to our future programming of scalable and usable code.
Continue to expand the introduction of the above resource interface as a raw package of resources, which inherits from Inputstreamresource interfaces, Inputstreamresource only InputStream getInputStream () Such a method, through this inheritance, gives the function of obtaining the Inputstram stream through the resource object. Below look at the interface of the source code: Inputstreamresource Interface

Package Org.springframework.core.io;

Import java.io.IOException;
Import Java.io.InputStream;

/**
 * @author Juergen Hoeller
 * @since 20.01.2004 * * Public
interface Inputstreamsource {

    /**
     * Returns InputStream classes, such as file, Classpath resources, and byte array
     * @return InputStream Returns a new InputStream object
     * @throws IOException
     * *
    InputStream getInputStream () throws IOException;
}
Resource Interface
Package Org.springframework.core.io;
Import Java.io.File;
Import java.io.IOException;
Import Java.net.URI;

Import Java.net.URL;
 The/** * Resource Interface abstracts all the underlying resources used within spring: File, URL, Classpath, and so on. * At the same time, for resource files of different sources, resource also has different implementations: file (filesystemresource), classpath resource (classpathresource), * URL resource (urlresource),
 InputStream Resources (Inputstreamresource), byte array (bytearrayresource), and so on.
     * * @author Juergen Hoeller * @since 28.12.2003 * * Public interface Resource extends Inputstreamsource {/**

    * To determine whether a resource exists * @return Boolean exists/Boolean exists ();

    /** * To determine whether the resource is readable * @return Boolean is readable/boolean isreadable ();

    /** * is in the open state * @return Boolean Open/Boolean IsOpen (); /** * Get URL type resource for resource conversion * @return URL get URL type * @throws IOException throw an exception if the resource cannot be opened * * URL GetURL () t

    Hrows IOException; /** * Gets the URI type resource for the resource conversion * @return URI gets the URI type * @throws IOException throws an exception if the resource cannot be opened/URI GetURI () t HRows IOException; /** * Gets the file type resource for the resource conversion * @return file gets the file type * @throws IOException throws an exception if the resource cannot be opened/file Getfil

    E () throws IOException; /** * Get Resource length * @return Long resource length * @throws IOException Throw an exception if the resource cannot be opened/long contentlength () throw

    s IOException; /** * Gets the LastModified property * @return Long gets the lastmodified * @throws IOException throws an exception if the resource cannot be opened */long L

    Astmodified () throws IOException; /** * Create a relative resource method * @param relativepath relative path * @return Resource returns a new resource * @throws IOException If resources cannot be hit

    Open then throw an exception * * Resource createrelative (String relativepath) throws IOException;

    /** * Get file name * @return String file name or null */String GetFileName ();
/** * Get error handling information, mainly used for error handling information printing * @return string Error resource Information */String getdescription (); }
Classpathresource

And then look at the implementation of the resource interface we used in the above code Classpathresource part of the need to focus on the source code

Package Org.springframework.core.io;
Import java.io.FileNotFoundException;
Import java.io.IOException;
Import Java.io.InputStream;

Import Java.net.URL;
Import Org.springframework.util.Assert;
Import Org.springframework.util.ClassUtils;
Import Org.springframework.util.ObjectUtils;

Import Org.springframework.util.StringUtils; 
 /** * @author Juergen Hoeller * @author Sam Brannen * @since 28.12.2003 * @see classloader#getresourceasstream (String)

    * @see Class#getresourceasstream (String) */public Class Classpathresource extends Abstractfileresolvingresource {

    Private final String path;

    Private ClassLoader ClassLoader;


    Private class<?> Clazz; /** creates a Classpathresource object through the path of the resource/public Classpathresource (String path) {This path, ClassLoader
    ) null); /** the concrete implementation of the above construction method */Public Classpathresource (String path, ClassLoader ClassLoader) {assert.no
        Tnull (Path, "path must not being null"); String Pathtouse= Stringutils.cleanpath (path);
        Remove the top/if (Pathtouse.startswith ("/")) {pathtouse = pathtouse.substring (1) of the path;
        } This.path = Pathtouse;
    This.classloader = (ClassLoader!= null? ClassLoader:ClassUtils.getDefaultClassLoader ());
     /** * Create A new {@code Classpathresource} for {@code Class} usage.
     * The path can be relative to the given class, or absolute within * classpath via a leading slash. * @param path relative or absolute path within the class path * @param clazz the class to load resources with *
        @see Java.lang.class#getresourceasstream */public Classpathresource (String path, class<?> clazz) {
        Assert.notnull (Path, "path must not being null");
        This.path = Stringutils.cleanpath (path);
    This.clazz = Clazz;
     /** obtains Inputstram's specific implementation * This implementation opens a InputStream for the given class path resource. * @see Java.lang.Classloader#getresourceasstream (String) * @see Java.lang.class#getresourceasstream (String) * * @Override
        Public InputStream getInputStream () throws IOException {InputStream is;
        if (This.clazz!= null) {is = This.clazz.getResourceAsStream (This.path);
        else if (This.classloader!= null) {is = This.classLoader.getResourceAsStream (This.path);
        else {is = Classloader.getsystemresourceasstream (This.path); } if (is = = null) {throw new FileNotFoundException (getdescription () + "cannot be opened because it D
        OES not exist ");
    return is; /** gets the filename * This implementation returns the name of the file, this class path * resource refers
     To.
        * @see Org.springframework.util.stringutils#getfilename (String) */@Override public String GetFileName () {
    Return Stringutils.getfilename (This.path); }

}
 
Defaultlistablebeanfactory class

We've learned about interfaces and implementations at the resource level, and here's an analysis of the defaultlistablebeanfactory factory = new Defaultlistablebeanfactory () in our previous code. Here we have introduced a new class defaultlistablebeanfactory, which can be seen from the IOC class diagram as a default implementation class for Beanfactory, whose instance object can be used as an independent IOC container, You can think of this object as a container that holds the Bean object, and our well-defined bean object, after spring loading and loading, is eventually managed by the change factory, and we need to get the bean object.

We call its parameterless construct method to create the factory object and see what's going on down the bottom.

@SuppressWarnings ("Serial") public
class Defaultlistablebeanfactory extends Abstractautowirecapablebeanfactory
        implements Configurablelistablebeanfactory, Beandefinitionregistry, Serializable {

    /**
     * Create a new Defaultlistablebeanfactory.
     *
    /Public defaultlistablebeanfactory () {
        super ();//Calling the parent class's parameterless constructor
    }
}

Next trace the parent class abstractautowirecapablebeanfactory source abstractautowirecapablebeanfactory class

Public abstract class Abstractautowirecapablebeanfactory extends Abstractbeanfactory
        implements autowirecapablebeanfactory {

    /**
     * Create a new abstractautowirecapablebeanfactory.
    /Public Abstractautowirecapablebeanfactory () {
        super ();//Abstractbeanfactory constructor method for parent class, code below ↓↓↓
        Ignoredependencyinterface (beannameaware.class);
        Ignoredependencyinterface (beanfactoryaware.class);
        Ignoredependencyinterface (Beanclassloaderaware.class);
    }
Abstractbeanfactory class
Public abstract class Abstractbeanfactory extends Factorybeanregistrysupport implements Configurablebeanfactory {
    /**
     * Create a new abstractbeanfactory.
     *
    /Public abstractbeanfactory () {
        //However, nothing has been done here
    }
}
beandefinition loading, parsing and registration

We created the defaultlistablebeanfactory object and already have the container to hold the bean, but we can see from the source that we have not yet done other practical operations on the factory. There's nothing in there. So, we define how the bean defined by the configuration file enters the spring container, and we have to continue parsing the following code. We first analyze the implementation of Xmlbeandefinitionreader reader = new Xmlbeandefinitionreader (Factory).
From the Xmlbeandefinitionreader class name We also see a term beandefinition, we first understand the role of beandefinition in the next spring.

The function of beandefinition, similar to the resource interface, is to provide a layer of abstraction for all beans, and to encapsulate all forms of objects into a data structure that facilitates coordinated management and scheduling within spring. Beandefinition masks the differences between different objects for the spring framework.

Then we look at the key parts of the Xmlbeandefinitionreader class source Xmlbeandefinitionreader class

public int loadbeandefinitions (Resource Resource) throws Beandefinitionstoreexception {/ /to resource parameters first to do a layer of encapsulation processing, mainly in order to obtain getreader () the implementation of this method, the source code in the following ↓↓↓↓return loadbeandefinitions (new Encodedresource (Resource    
)); public int loadbeandefinitions (Encodedresource encodedresource) throws Beandefinitionstoreexception {Assert.no
        Tnull (Encodedresource, "Encodedresource must not to be null"); if (logger.isinfoenabled ()) {Logger.info ("Loading XML bean Definitions from" + Encodedresource.getresour
        CE ());
        } set<encodedresource> currentresources = This.resourcesCurrentlyBeingLoaded.get ();
                if (currentresources = = null) {currentresources = new hashset<encodedresource> (4); This.resourcesCurrentlyBeingLoaded.set (currentresources); 

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.