Research on the IOC source code for spring Web launch

Source: Internet
Author: User

    1. Research IOC first create a simple Web project, and we'll add a sentence to the XML.
<context-param>        <param-name>contextConfigLocation</param-name>        <param-value> classpath:applicationcontext.xml</param-value>    </context-param>    <listener>        < Listener-class>org.springframework.web.context.contextloaderlistener</listener-class>    </ Listener>

This means that when the Web container starts, it enters the Contextloaderlistener class first, and then loads the Applicationcontext.xml file under Classpath. So the focus is on the Contextloaderlistener, point open Source code:

/**     * Initialize The root Web application context.     */    @Override public    void contextinitialized (Servletcontextevent event) {        Initwebapplicationcontext ( Event.getservletcontext ());    }    /**     * Close The root Web application context.     */    @Override public    void contextdestroyed (Servletcontextevent event) {        Closewebapplicationcontext ( Event.getservletcontext ());        Contextcleanuplistener.cleanupattributes (Event.getservletcontext ());    }

The two implementations of the Servletcontextlistener interface are mainly used. The Web container first calls the Contextinitialized method, passes in the Tomcat encapsulated container resource, and then calls the parent class's initialization container method.

/*** The root Webapplicationcontext instance that this loader manages.*/private webapplicationcontext context;public WebA Pplicationcontext Initwebapplicationcontext (ServletContext servletcontext) {.....             Omit//Store context in the local instance variable, to guarantee that//It's available on ServletContext shutdown.            if (This.context = = null) {This.context = Createwebapplicationcontext (ServletContext); } if (This.context instanceof configurablewebapplicationcontext) {Configurablewebapplicati                Oncontext CWAC = (configurablewebapplicationcontext) this.context;                    if (!cwac.isactive ()) {//the context has not yet been refreshed, provide services such as Setting the parent context, setting the application context ID, etc if (cwac.getparent ( ) = = null) {//The context instance is injected without an explicit PARent//Determine parent for root Web application context, if any.                        ApplicationContext parent = Loadparentcontext (ServletContext);                    Cwac.setparent (parent);                } configureandrefreshwebapplicationcontext (CWAC, ServletContext); }} servletcontext.setattribute (Webapplicationcontext.root_web_application_context_attribute, THIS.C            Ontext);            ClassLoader CCL = Thread.CurrentThread (). Getcontextclassloader ();            if (CCL = = ContextLoader.class.getClassLoader ()) {currentcontext = This.context;            } else if (CCL! = null) {Currentcontextperthread.put (CCL, this.context); }  ......            Omit return this.context; }

The main step of this method is the Createwebapplicationcontext method used to create the root container of Xmlwebapplicationcontext, which is taken from servletcontextevent.

The Loadparentcontext method is used to load the parent container. The Main method Configureandrefreshwebapplicationcontext is used to configure and refresh the root container, the most important thing in the method is the Refresh method, which implements the most important function.

@Override public void Refresh () throws Beansexception, IllegalStateException {synchronized (This.startupshutdow            Nmonitor) {//Prepare this context for refreshing.            Preparerefresh ();            Tell the subclass to refresh the internal bean factory.            Configurablelistablebeanfactory beanfactory = Obtainfreshbeanfactory ();            Prepare The Bean factory for use with this context.            Preparebeanfactory (beanfactory);                try {//allows post-processing of the Bean factory in context subclasses.                Postprocessbeanfactory (beanfactory);                Invoke factory processors registered as beans in the context.                Invokebeanfactorypostprocessors (beanfactory);                Register Bean processors that intercept bean creation.                Registerbeanpostprocessors (beanfactory);                Initialize message source for this context.     Initmessagesource ();           Initialize Event Multicaster for this context.                Initapplicationeventmulticaster ();                Initialize other special beans in specific context subclasses.                Onrefresh ();                Check for listener beans and register them.                Registerlisteners ();                Instantiate all remaining (Non-lazy-init) singletons.                Finishbeanfactoryinitialization (beanfactory);                Last Step:publish corresponding event.            Finishrefresh ();  } catch (Beansexception ex) {Logger.warn ("Exception encountered during context initialization-                Cancelling refresh attempt ", ex);                Destroy already created singletons to avoid dangling resources.                Destroybeans ();                Reset ' active ' flag.                CancelRefresh (ex);                Propagate exception to caller.            Throw ex; }        }    }

The Preparerefresh method is used to prepare the environment to be used later.

Obtainfreshbeanfactory method gets Beanfactory

@Override    protected final void Refreshbeanfactory () throws Beansexception {        if (hasbeanfactory ()) {            Destroybeans ();            Closebeanfactory ();        }        try {            Defaultlistablebeanfactory beanfactory = Createbeanfactory ();            Beanfactory.setserializationid (GetId ());            Customizebeanfactory (beanfactory);            Loadbeandefinitions (beanfactory);            Synchronized (this.beanfactorymonitor) {                this.beanfactory = beanfactory;            }        }        catch (IOException ex) {            throw new applicationcontextexception ("I/O error parsing bean definition source for" + getd Isplayname (), ex);        }    }

The beanfactory that is actually returned is the implementation class defaultlistablebeanfactory, which instantiates the class that is used to instantiate the XML after it is loaded.

Loadbeandefinitions is an important method for really loading classes, and it's all about getting ready for work.

@Override    protected void loadbeandefinitions (Defaultlistablebeanfactory beanfactory) throws Beansexception, IOException {        //Create A new xmlbeandefinitionreader for the given beanfactory.        Xmlbeandefinitionreader Beandefinitionreader = new Xmlbeandefinitionreader (beanfactory);        Configure The bean definition reader with this context ' s        //resource loading environment.        Beandefinitionreader.setenvironment (Getenvironment ());        Beandefinitionreader.setresourceloader (this);        Beandefinitionreader.setentityresolver (New Resourceentityresolver (this));        Allow a subclass to provide custom initialization of the reader,        //Then proceed with actually loading the bean def Initions.        Initbeandefinitionreader (Beandefinitionreader);        Loadbeandefinitions (Beandefinitionreader);    }

Overwrite this method in Xmlwebapplicationcontext, internally creating the Xmlbeandefinitionreader class, which is used as a read operator of the Bean in the XML, initializing the environment and loading the class

    protected void Loadbeandefinitions (Xmlbeandefinitionreader reader) throws IOException {        string[] configlocations = Getconfiglocations ();        if (configlocations! = null) {for            (String configlocation:configlocations) {                reader.loadbeandefinitions ( configlocation);}}}    

This configuration file is loaded with Xmlbeandefinitionreader after obtaining the configuration file information (for example: Classpath:applicationContext.xml) that was placed in the array prior to initialization.

The XML file information is then encoded and decoded:

    /**     * Load Bean definitions from the specified XML file.     * @param resource The Resource descriptor for the XML file * @return The number of the     bean definitions found     * @throw s beandefinitionstoreexception in case of loading or parsing errors     */    @Override public    int Loadbeandefinitions (Resource Resource) throws Beandefinitionstoreexception {        return loadbeandefinitions (new Encodedresource (Resource));    }

Key steps:

InputStream InputStream = Encodedresource.getresource (). getInputStream ();            try {                InputSource inputsource = new InputSource (inputstream);                if (encodedresource.getencoding () = null) {                    inputsource.setencoding (encodedresource.getencoding ());                }                Return Doloadbeandefinitions (InputSource, Encodedresource.getresource ());            }            finally {                inputstream.close ();            }

After the formal load gets to the XML resource parsing

protected int doloadbeandefinitions (InputSource inputsource, Resource Resource)            throws beandefinitionstoreexception {            Document doc = doloaddocument (InputSource, Resource);            Return Registerbeandefinitions (Doc, Resource);    }

The main step is to parse the XML file into the document element with sax and register it in the Beandefinitions container.

The processing method of the Doloaddocument method and the way Sax handles XML documents are almost the same, so you can refer to the SAX parsing XML process

The process of parsing is many, such as

    private void Parsedefaultelement (Element ele, beandefinitionparserdelegate delegate) {        if ( Delegate.nodenameequals (Ele, import_element)) {//Parse IMPORT            importbeandefinitionresource (ele);        }        else if (delegate.nodenameequals (Ele, alias_element)) {//Parse ALIAS            processaliasregistration (ele);        }        else if (delegate.nodenameequals (Ele, bean_element)) {//Parse BEAN            processbeandefinition (Ele, delegate);        }        else if (delegate.nodenameequals (Ele, nested_beans_element)) {//Parse BEANS            //recurse            Doregisterbeandefinitions (ele);        }    }

The individual labels are parsed and injected into the container.

Research on the IOC source code for spring Web launch

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.