In software development, if some features are used more commonly, these features can often be implemented as platform features, which are effectively encapsulated in these platform features to open to other applications. As such, Spring has played an application platform because of its IOC, AOP, transaction processing, and persistence-driven features. Spring MVC is an important part of spring, and the implementation of its Web application is supported by spring, and spring MVC is implemented based on the basic features provided by the spring platform. This article is mainly about the process of Spring MVC container initialization, from which we can see spring MVC's dependence on spring. first, from the Web application perspective of Spring MVC
In the servlet model, the implementation of the request-response relies on the co-ordination of the two major elements:
1. Configuring the servlet and its mapping relationship (in Web. xml)
2. Complete the response logic in the Servlet implementation class
After the project scale expands, the request-response mappings are all defined in Web. XML and will cause the expansion of Web. Xml to become difficult to maintain. To address this problem, SPRINGMVC proposes a solution that refines a core servlet to overwrite all HTTP requests. This refined servlet is often called the core dispatcher . In Springmvc, the core dispatcher is Org.springframework.web.servlet.DispatcherServlet.
The core dispatcher is addressing the following two issues:
Issue 1: The core servlet should be able to establish a complete set of processes for normalizing all HTTP requests.
Issue 2: The core servlet should be able to distribute different HTTP requests to different servlet objects for processing according to certain rules.
For the two problems above, SPRINGMVC's solution is to normalize the entire process and assign each process step to a different component for processing .
Process Normalization: divides the processing process into several steps (tasks) and concatenates all the steps using a clear logical mainline
Process Process components: Define each step (task) in the processing process as an interface and give each interface a different implementation pattern
The primary content of process normalization is to consider the logical steps that a generic servlet responder should roughly include: preliminary processing of HTTP requests, lookup of corresponding controller processing classes (methods) to invoke corresponding controller processing classes (methods) to complete business logic Handling exceptions that can occur when a controller processes a class (method) call the HTTP response processing based on the call result of the Controller processing class (method)
The so-called component, in fact, is the use of programming language to express these logical semantics. In the Java language, the syntax structure that best fits the semantics of the logic processing is the interface, and the interface can have different implementations, so the above four processes are also defined for four different interfaces, respectively: Handlermapping handleradapter Handlerexceptionresolver viewresolver Two, spring MVC from the spring perspective
As can be seen from the above, the component is the core of the core dispatcher (Dispatchservlet), which is the logical carrier of HTTP request processing, Dispatcherservlet is the dispatch center of the logical processing, and the component is the Operation object that is dispatched. The role of the spring container here is to assist Dispatcherservlet to better manage the components.
We know that the SPRINGMVC component is an interface definition, when we define a component in the core configuration file of Springmvc, we use the implementation class of the component, specify the behavior pattern of the component with the concrete implementation class, and the different implementation classes represent different behavior patterns. They can coexist in spring. The spring container manages these implementation classes, depending on how it is used, as determined by the application itself.
Pictured above is a picture of the official spring reference, Dispatchservlet requests to receive HTTP, and the processing of the request is done by components, and the component interface is implemented by the spring IOC container (Webapplicationcontext) to manage. As we can see from this diagram, Spring MVC's implementation of Web applications is dependent on the underlying features (IOC, etc.) provided with spring. The difference between the two webapplicationcontext in the figure is left below. iii. Spring MVC Portal Configuration file Web. XML
What are the configuration files for Spring MVC: The Portal Configuration file: Web. xml; The configuration file that is loaded for each Web project by the website or application server. Application context: Includes the web framework-specific configuration file: Springmvc's ${dispatcherservletname}-servlet.xml configuration file. And spring's configuration file applicationcontext.xml,applicationcontext-*.xml.
Following the servlet specification, the Portal configuration file for Spring MVC's Web App is also XML. The initialization of a Web container is the first load of the. xml file, which jetty loads and initializes the configuration file at startup, and listener and servlets defined therein. Jetty does not know (and does not care) the existence of other profiles, so loading other profiles should be your (framework) thing. So how to load it. As I said earlier, Jetty automatically loads and initializes listener and servlets at startup, so we can customize a listener (Contextloaderlistener) or servlet (Dispatcherservlet). Jetty will load and initialize them according to Web. XML, while they are responsible for loading the appropriate configuration files.
In the Web. XML configuration file, there are two main configurations: Contextloaderlistener and Dispatcherservlet. The same configuration about the spring configuration file also has two parts: the Init-param in Context-param and Dispatcherservlet. The distinction between these two parts, then, is the initialization of the spring container and the initialization of the Web container. Dispatcherservlet and Contextloaderlistener provide the interface to spring in the Web container. ServletContext provides a hosting environment for the spring IOC container, in which spring MVC establishes an IOC container system.
Here's a look at the related configuration of the Web. xml file in spring MVC:
<?xml version= "1.0" encoding= "UTF-8"?> <web-app version= "2.5" xmlns= "Http://java.sun.com/xml/ns/javaee" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" & nbsp;xsi:schemalocation= "Http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" > <display-name>push-center-server</display-name> <description>< Span style= "font-family:arial, Sans-serif;" >test</span></description> <context-param> < param-name>webapprootkey</param-name> <param-value>test</param-value > </context-param> <context-param> <param-name& gt;contextconfiglocation</param-name> <param-value> Classpath:applicationcOntext.xml </param-value> </context-param> <conte xt-param> <param-name>log4jConfigLocation</param-name> <param-value>classpath:log4j2.xml</param-value> </context-param> <!--the profile location used by the project. Project start automatically read- <context-param> <param-name >propertiesConfigLocation</param-name> <param-value>/web-inf/conf/ config.properties</param-value> </context-param> <!--jmonitor-->
<context-param> <param-name>jmonitor-configfile</param-name> <param-value>jmonitor.properties</param-value> </ context-param> <listener> <listener-class>com.meituan.jmonitor.servlet.ContextListener</listener-class> </ listener> <listener> <listener-class> org.springframework.web.util.log4jconfiglistener</listener-class> </listener> <listener> <listener-class>
org.springframework.web.context.contextloaderlistener</listener-class> </listener> <listener> <listener-class> &NBSP ;
Org.springframework.web.context.request.RequestContextListener </listener-class> </listener> <!--jmonitor http collector--> <filter> <filter-name>JMonitorHttpMonitorFilter</filter-name> < Filter-class>com.meituan.jmonitor.collector.http.httpmonitorfilter</filter-class> </filter> <filter-mapping> <filter-name>jmonitorhttpmonitorfilter</ filter-name> <url-pattern>/*</url-pattern> </ filter-mapping> <servlet> <servlet-name>appservlet</ servlet-name> <servlet-class>com.sankuai.meituan.web.mtdispatcherservlet</ servlet-class> <init-param> <param-name& gt;contextconfiglocation</param-name> <param-value>classpath: webmvc-config.xml</param-value> </init-param> < load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern> </servlet-mapping> </web-app>
Iv. Initialization of the Spring IOC container (root context)
The spring framework itself does not have Web functionality, and spring MVC uses the Webapplicationcontext interface to extend ApplicationContext, making it Web-enabled, The default implementation of the Webapplicationcontext interface is xmlwebapplicationcontext. So, how does Spring MVC create an IOC container in a Web environment?
First look at the source code of Webapplicationcontext,
Webapplicationcontext
Public interface Webapplicationcontext extends ApplicationContext {
//for accessing the root context in ServletContext
String root_ Web_application_context_attribute = WebApplicationContext.class.getName () + ". ROOT ";
String scope_request = "REQUEST";
String scope_session = "SESSION";
String scope_global_session = "Globalsession";
String scope_application = "Application";
String servlet_context_bean_name = "ServletContext";
String context_parameters_bean_name = "Contextparameters";
String context_attributes_bean_name = "ContextAttributes";
Gets the current web container's ServletContext
servletcontext getservletcontext ();
}
In spring MVC, Spring context exists as a parent-child inheritance structure. A root context exists in the Web environment (ServletContext), which is the root context of the entire application and is the parent context of the other context. Spring MVC also holds a separate context, which is the child context of the root contexts.
The context that is first initiated by Contextloaderlistener is the root context that accompanies the ServletContext, and on the basis of the root context, Spring MVC corresponds to the child context of the object that is held to manage the controller's needs. The following figure is the Contextloaderlistener inheritance, which implements the Servletcontextlistener interface, which provides callbacks that are combined with the servlet life cycle, such as contextinitialized and contextdestroyed methods. The process of establishing the Webapplicationcontext is done in the Contextinitialized interface implementation, and the process of loading the IOC container is done by Contextloader.
Contextloaderlistener
public class Contextloaderlistener extends Contextloader implements Servletcontextlistener {private Contextloader con
Textloader; Public Contextloaderlistener () {} public Contextloaderlistener (Webapplicationcontext context) {SUP
ER (context);
} public void Contextinitialized (Servletcontextevent event) {This.contextloader = Createcontextloader ();
if (This.contextloader = = null) {This.contextloader = this;
} this.contextLoader.initWebApplicationContext (Event.getservletcontext ());
} @Deprecated protected Contextloader Createcontextloader () {return null;
} @Deprecated Public Contextloader Getcontextloader () {return this.contextloader;
} public void Contextdestroyed (Servletcontextevent event) {if (This.contextloader! = null) {
This.contextLoader.closeWebApplicationContext (Event.getservletcontext ());
} Contextcleanuplistener.cleanupattributes (Event.getservletcontext ()); }
From the Contextloaderlistener source can be seen, the implementation is the Servletcontextlistener interface, this interface function will be combined with the Web container life cycle is called. Because Servletcontextlistener is a listener for ServletContext, when ServletContext starts or stops, it triggers a response event, and the listener Servletcontextlistener receives the event, Will respond accordingly, such as the Contextinitialized method and the Contextdestroyed method here. The generation and destruction of the Spring IOC container (root context) is through this two method, so the root context is associated with ServletContext.
So when the Web app starts, the Contextinitialized method executes the load root context (the IOC container) by first getting ServletContext from the servlet event and then ServletContext as the hosting environment. Loaded into the root context (IOC container), the specific onboarding process is handled by Contextloader.
The following figure shows the loading process for the root context, which will be combined with the source code to see how this process is implemented.
The loading process for the root context:
ROOT context is configured in Contextloaderlistener, Contextloaderlistener reads contextconfiglocation specified configuration file in Context-param, Create a root Context. Here's a look at the source of the context created in Contextloaderlistener:
Contextloader loading the root context source code
This starts the initialization of the Webapplicationcontext public webapplicationcontext initwebapplicationcontext (ServletContext ServletContext) {//In the entire Web application, there can be only one root context to determine if ServletContext has a root context if (Servletcontext.getattribute (Webapplicati
Oncontext.root_web_application_context_attribute) = null) {throw new IllegalStateException ( "Cannot initialize context because there is already a root application context present-" + "Chec
K Whether you had multiple contextloader* definitions in your web.xml! ");}
Log logger = Logfactory.getlog (Contextloader.class);
ServletContext.log ("Initializing Spring root Webapplicationcontext");
if (logger.isinfoenabled ()) {Logger.info ("Root webapplicationcontext:initialization started");
} Long StartTime = System.currenttimemillis (); try {//Store context in local instance variable, to guarantee that//It's available on SerVletcontext shutdown. if (This.context = = null) {//performed the operation to create Webapplicationcontext this.context = Createwebapplicationcontext (SE
Rvletcontext); } if (This.context instanceof configurablewebapplicationcontext) {Configurablewebapplicationc
Ontext 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.getpare
NT () = null) {//The context instance is injected without an explicit parent
Determine parent for root Web application context, if any.
The parent context loaded into the root context applicationcontext parent = Loadparentcontext (ServletContext);
Cwac.setparent (parent);
} Configureandrefreshwebapplicationcontext (CWAC, ServletContext); }}//Place the root context in ServletContext Servletcontext.setattribute (webapplicationcontext.root_web_applic
Ation_context_attribute, This.context);
ClassLoader CCL = Thread.CurrentThread (). Getcontextclassloader ();
if (CCL = = ContextLoader.class.getClassLoader ()) {currentcontext = This.context;
} else if (CCL! = null) {Currentcontextperthread.put (CCL, this.context); } if (logger.isdebugenabled ()) {Logger.debug ("Published root webapplicationcontext as Servlet Context attribute with Name ["+ Webapplicationcontext.root_web_application_context_attribute +"]
");
} if (logger.isinfoenabled ()) {Long elapsedtime = System.currenttimemillis ()-startTime; Logger.info ("Root webapplicationContext:initialization completed in "+ ElapsedTime +" MS ");
} return this.context;
} catch (RuntimeException ex) {logger.error ("Context initialization Failed", ex);
Servletcontext.setattribute (Webapplicationcontext.root_web_application_context_attribute, ex);
Throw ex;
} catch (Error err) {logger.error ("Context initialization Failed", err);
Servletcontext.setattribute (Webapplicationcontext.root_web_application_context_attribute, err);
throw err; }} protected Webapplicationcontext Createwebapplicationcontext (ServletContext SC) {//According to the configuration in Web. XML, decide to use that Weba
Pplicationcontext, default with xmlwebapplicationcontext class<?> Contextclass = Determinecontextclass (SC); Determine if Contextclass inherits Configurablewebapplicationcontext or is its interface implements if (! ConfigurableWebApplicationContext.class.isAssignableFrom (Contextclass)) {throw new appliCationcontextexception ("Custom context class [" + Contextclass.getname () + "] is not of type [" + Conf
IgurableWebApplicationContext.class.getName () + "]");
}//Direct instantiation of the required IOC container return (configurablewebapplicationcontext) Beanutils.instantiateclass (Contextclass); }//Set the IOC container parameters and then start the container initialization with refresh protected void Configureandrefreshwebapplicationcontext ( Configurablewebapplicationcontext WAC, ServletContext SC) {//Set Application context ID if (Objectutils.identitytos
Tring (WAC). Equals (Wac.getid ())) {//The application context ID is still set to its original default value -Assign a more useful ID based on available information String idparam = Sc.getinitparameter (
Context_id_param);
if (idparam! = null) {Wac.setid (idparam); } else {//Generate default ID ... if (sc.getmajorversion () = = 2 && sc . getminorversiOn () < 5) {//Servlets <= 2.4:resort to name specified in Web. XML, if any. Wac.setid (Configurablewebapplicationcontext.application_context_id_prefix + objectutils.getdi
Splaystring (Sc.getservletcontextname ()));
} else {Wac.setid (Configurablewebapplicationcontext.application_context_id_prefix +
Objectutils.getdisplaystring (Sc.getcontextpath ()));
}}}//Set ServletContext Wac.setservletcontext (SC);
Set the location parameter of the configuration file String Initparameter = Sc.getinitparameter (Config_location_param);
if (initparameter! = null) {wac.setconfiglocation (initparameter);
}//Before refresh, re-customize (Customize) Configurablewebapplicationcontext Customizecontext (SC, WAC) According to the configured config locations;
Initiates the initialization of the container Wac.refresh (); }
As can be seen from the source code above, the IOC container launch process in the Web container is similar to the way in which the IOC container is launched in the application, the difference is that it is necessary to consider the characteristics of the environment of the Web container, such as the setting of various parameters, the combination of IOC container and Web container servletcontext, etc. After the context is initialized, the context is stored and servletcontext, creating a global context for the entire application, the so-called root context. At the same time, when starting spring MVC, Dispatchservlet is setting the root context to its own parent context when initializing the context in which it holds itself.
http://blog.csdn.net/and1kaney/article/details/51214193 This article can see the entire call hierarchy of the root container initialization process. v. Initialization of the Spring MVC container (child context)
The above is the loading and initialization of the root context in the Web container, and after the initialization of the Contextloaderlistener, the Web container begins to initialize the Dispatchservlet, Dispatchservlet will create its own context to manage the bean objects of spring mvc. In establishing this own context, the root context is obtained from the ServletContext as the parent context of the context in which the dispatchservlet holds, and the context in which it holds is initialized. Finally, the context that you hold is also saved to ServletContext.
Let's take a look at the inheritance of Dispatchservlet, as shown below. Dispatchservlet inherited the HttpServlet by inheriting Frameworkservlet and Httpservletbean. Httpservletbean is spring's lowest-level abstraction for servlets. In this layer of abstraction, spring will treat this servlet as a spring bean and inject the value from the Init-param parameter defined in Web portal Config. xml dispatchservlet into the Bean's properties.
Dispatcherservlet is also a servlet, based on the definition of the servlet specification, the two core methods in the servlet are the Init method and the service method:
1. Init method
Run when the entire system is started and run only once. Therefore, in the Init method we tend to initialize the entire application. These initialization operations may include initialization of the container (Webapplicationcontext), initialization of components and external resources, and so on.
2. Service Methods
Listens for and processes all Web requests while the entire system is running in a listening mode. So what we see in the service and its related methods is the process of handling HTTP requests.
This article mainly introduces the initialization of the spring MVC container, so it mainly introduces the Init method of Idisipatchservlet.
Httpservletbean
@Override public final void Init () throws Servletexception {if (logger.isdebugenabled ()) {
Logger.debug ("Initializing servlet" + getservletname () + "'");
}//Set bean properties from init parameters. try {///read <init-param> in the Dispatchservlet definition in Web. XML, and configure the Bean property Prop