Spring's application initialization process has not been understood and has just encountered a related problem. Decided to take a good look at this process. In our project to develop spring, we will basically go through the Web. XML:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/web-inf/conf/application-*.xml
</param-value>
</context-param>
To initialize the individual spring configuration files, but we just know what the code does, and it's not clear why we can initialize the configuration file after we've configured the code. And of course we'll add:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
This one listener, I first will want to contextconfiglocation this must be able to find in Contextloaderlistener this class, open the source code, This listener is implemented Servletcontextlistener this interface, this interface only two methods:
public interface Servletcontextlistener
Extends EventListener
{
public abstract void contextinitialized (Servletcontextevent servletcontextevent);
public abstract void contextdestroyed (Servletcontextevent servletcontextevent);
}
And it is inherited EventListener this interface, open this interface code surprised me, there is no way to do nothing:
Package java.util;
public interface EventListener
{
}
And it's java.util, not something in spring.
After finding it and not finding it, back to the Contextloaderlistener class method, the Contextinitialized method is used to initialize the context:
public void contextinitialized (Servletcontextevent event)
{
Contextloader = Createcontextloader ();
Contextloader.initwebapplicationcontext (Event.getservletcontext ());
}
There is a Createcontextloader method in the method:
Protected Contextloader Createcontextloader ()
{
return new Contextloader ();
}
This method returns a Contextloader instance, enters into the Contextloader class, presses CTRL+F to look for the contextconfiglocation, then does not appear the computer's thump sound, has found it:
Protected Webapplicationcontext Createwebapplicationcontext (ServletContext ServletContext, ApplicationContext Parent)
Throws Beansexception
{
Class contextclass = Determinecontextclass (ServletContext);
if (! ( Org.springframework.web.context.ConfigurableWebApplicationContext.class). IsAssignableFrom (Contextclass))
{
Throw new Applicationcontextexception ("Custom context class [" + Contextclass.getname () + "] is not of type [" + (org . Springframework.web.context.ConfigurableWebApplicationContext.class). GetName () + "]");
} else
{
Configurablewebapplicationcontext WAC = (configurablewebapplicationcontext) Beanutils.instantiateclass (Contextclass);
Wac.setparent (parent);
Wac.setservletcontext (ServletContext);
Wac.setconfiglocation (Servletcontext.getinitparameter ("<span style=" color: #ff0000; " >contextConfigLocation</span> "));
Customizecontext (ServletContext, WAC);
Wac.refresh ();
return WAC;
}
}
Through the code, Configurablewebapplicationcontext sets the value of the parameter obtained from ServletContext and then enters the Configurablewebapplicationcontext code. It's just an interface that goes into the Staticwebapplicationcontext Setconfiglocation method:
public void Setconfiglocation (String configlocation)
{
if (configlocation! = null)
throw new Unsupportedoperationexception ("Staticwebapplicationcontext does not the support config locations");
Else
Return
}
It is strange in this method to throw an exception when the argument is not empty, to view the spring's documentation: the class StaticWebApplicationContext
does not the supported this method. It's the kind of thing that doesn't support it, and it's stuck again. Back again, look at this sentence:
Configurablewebapplicationcontext WAC = (configurablewebapplicationcontext) Beanutils.instantiateclass ( Contextclass);
Spring uses Beanutils to initialize the class instance of Contextclass, Contextclass is obtained by the following code:
Protected Class Determinecontextclass (ServletContext servletcontext)
Throws Applicationcontextexception
{
String contextclassname = Servletcontext.getinitparameter ("Contextclass");
if (contextclassname! = null)
Try
{
Return Classutils.forname (Contextclassname);
}
catch (ClassNotFoundException ex)
{
throw new Applicationcontextexception ("Failed to load Custom context class [" + Contextclassname + "]", ex);
}
Contextclassname = Defaultstrategies.getproperty ((org.springframework.web.context.WebApplicationContext.class). GetName ());
Try
{
Return Classutils.forname (Contextclassname, (org.springframework.web.context.ContextLoader.class). getClassLoader ());
}
catch (ClassNotFoundException ex)
{
throw new Applicationcontextexception ("Failed to load Default context class [" + Contextclassname + "]", ex);
}
}
The reflection is used here, and then the Instantiateclass method of Beanutils is seen:
Return Instantiateclass (Clazz.getdeclaredconstructor ((class[) null), NULL);
The construction method of Contextclass is obtained by reflection. Here are the overloads of the Instantiateclass method, mainly the following two lines of code:
Reflectionutils.makeaccessible (ctor);
Return ctor.newinstance (args);
ctor is the construction method of Contextclass by reflection, and args is the parameter in the construction method. This is null, which indicates that the new Contextclass method is not constructed.
And then back to determinecontextclass this method, we mainly look at:
Contextclassname = Defaultstrategies.getproperty ((org.springframework.web.context.WebApplicationContext.class). GetName ());
This code, we can guess it is through the properties of the GetProperty method to get Webapplicationcontext instances, then we went to the Webapplicationcontext this interface, This interface inherits the ApplicationContext interface, and we all know that our spring development will be through application ctx=new filesystemxmlapplicationcontext (" Beans.xml ") or ApplicationContext ctx=new classpathxmlapplicationcontext (" Beans.xml ") or ServletContext ServletContext = Request.getsession (). Getservletcontext (); ApplicationContext ctx = Webapplicationcontextutils.getwebapplicationcontext (ServletContext); There are three ways to get a applicationcontext, and then you can manipulate the beans in the configuration file. So here we're basically figuring out the process of initializing the spring configuration file.
Summary: By looking at the source code of these classes, the scope of the reflection use of Java is once again reflected. If I see something wrong or disagree with you, I would like to ask for it, and it is the first time that I have studied the problem.
Web. XML detailed contextconfiglocation turn