For Web. Xml I'm going to parse from the following points:
1. Contextloaderlistener: When the Web container is started, the configuration information of the ApplicationContext is automatically assembled.
2. Requestcontextlistener: Binds the HTTP request object to the thread that serves the request based on Localthread. This allows the bean with the request and session scope to be accessed in the subsequent call chain.
3, Dispatchservlet: Initializes the WEBMVC context. Responsible for the allocation of responsibilities.
Detailed analysis:
1, for Contextloaderlistener, start the Web container, automatically assemble ApplicationContext configuration information. This class Contextloaderlistener extends Contextloader implements Servletcontextlistener. Contextloaderlistener source code is very simple, the core is the implementation of the Servletcontextlistener contextinitialized and contextdestroyed method. Because the contextinitialized and contextdestroyed methods call each Contextloader inside the Initwebapplicationcontext and Closewebapplicationcontext methods. So the core is finally contextloader to implement the listener.
Contextloader has two important properties:
Contextconfiglocation: The directory where the configuration file specified in Web. XML is located, if not specified, Spring loads files that conform to *context.xml or Spring*.xml rules in the Web_inf directory.
Currentcontextperthread: The current webapplicationcontext is saved.
The Contextloader loading process can be described as:
First determine whether Webapplicationcontext exists, if not, initialize a xmlwebapplicationcontext (subclass of Webapplicationcontext) and put the instance into The Currentcontextperthread. When initializing Xmlwebapplicationcontext, use new Classpathxmlapplicationcontext (contextconfiglocation) with us The various beans we have configured are added to Xmlwebapplicationcontext, so we know that ApplicationContext offers a variety of Getbean methods ...
And you can see that Contextloader also provides a static way to get the current Webapplicationcontext: This is because the Initwebapplicationcontext initialization method plugs the created xmlwebapplicationcontext into the currentcontextperthread.
2. For Requestcontextlistener. Binds an HTTP request object to a thread that serves the request based on Localthread. This allows the bean with the request and session scope to be accessed in the subsequent call chain.
(1), request scope
<bean id= "loginaction" class= "com.test.LoginAction" scope= "Request"/>
For each HTTP request, the spring container creates a completely new instance of the Loginaction bean based on the loginaction bean definition, and the loginaction bean instance is only valid within the current HTTP request. As a result, you can safely change the internal state of the built instance as needed, and other requests that are created from an instance of the Loginaction bean definition will not see these state changes specific to a request. When the processing request ends, the bean instance of the request scope is destroyed.
(2), Session scope
<bean id= "userpreferences" class= "Com.foo.UserPreferences" scope= "Session"/>
For an HTTP session,spring container, an entirely new instance of the Userpreferences Bean is created based on the userpreferences bean definition, and the userpreferences Bean is only present in the current HTTP Session is valid. As with the request scope, you can safely change the internal state of the created instance as needed, while other HTTP sessions will not see the state changes that are specific to an HTTP session based on the instances created by Userpreferences. When the HTTP session is eventually discarded, the beans inside the HTTP session scope are discarded.
(3), Global session scope
<bean id= "userpreferences" class= "com.foo.UserPreferences" scope= "Globalsession"/>
The global session scope is similar to the standard HTTP session scope, but it only makes sense in portlet-based Web applications. The Portlet specification defines the concept of a global session, which is shared by all the various portlets that make up a portlet Web application. The bean defined in the global session scope is limited to the lifetime of the world Portlet session.
Why do I need additional configuration Requestcontextlistener?
Contextloaderlistener (or Contextloaderservlet) integrates the Web container with the spring container, Why is there an additional requestcontextlistener to support the other 3 scopes of the bean, because Contextloaderlistener implements the Servletcontextlistener listener interface, The Servletcontextlistener is only responsible for monitoring the startup and shutdown events of the Web container. The Requestcontextlistener implements the Servletrequestlistener listener interface, which listens for HTTP request events and notifies the listener every time a request is received by the Web server. The Requestcontextlistener,spring container is more closely combined with the Web container by configuring it.
3, Dispatchservlet: Initializes the WEBMVC context. Responsible for the allocation of responsibilities.
One: Initialize.
protected voidinitstrategies (ApplicationContext context) {Initmultipartresolver (context);//File Upload parsing, if the request type is multipart will be through the Multipartresolver file upload parsing;Initlocaleresolver (context);//Localization parsingInitthemeresolver (context);//Topic ResolutionInithandlermappings (context);//mapping requests to the processor via handlermappingInithandleradapters (context);//support for multiple types of processors via HandleradapterInithandlerexceptionresolvers (context);//If an exception is encountered during execution, it will be given to Handlerexceptionresolver to parseInitrequesttoviewnametranslator (context);//directly parse request to view nameInitviewresolvers (context);//by Viewresolver parsing the logical view name to a specific view implementationInitflashmapmanager (context);//Flash mapping Manager}
Second: The provision of services.
1. Save the site. Save the snapshot that the request is familiar with so that it can be restored if necessary.
2. Place the objects required by the framework into the request for use by view and handler.
3. Request a distribution service.
4. Restore the scene.
The code is as follows:
@Overrideprotected voidDoservice (HttpServletRequest request, httpservletresponse response)throwsException {if(logger.isdebugenabled ()) {String resumed= Webasyncutils.getasyncmanager (Request). Hasconcurrentresult ()? "Resumed": ""; Logger.debug ("Dispatcherservlet with Name" + getservletname () + "'" + resumed + "processing" + Request.getmethod () + "Request for [" + Getrequesturi (Request) + "]"); } //Keep A snapshot of the request attributes in case of an include,//To is able to restore the original attributes after the include.map<string, object> attributessnapshot =NULL; if(Webutils.isincluderequest (Request)) {Attributessnapshot=NewHashmap<string, object>(); Enumeration<?> Attrnames =Request.getattributenames (); while(Attrnames.hasmoreelements ()) {String Attrname=(String) attrnames.nextelement (); if( This. cleanupafterinclude | | Attrname.startswith ("Org.springframework.web.servlet") {attributessnapshot.put (Attrname, Request.getattribute (attrname)); } } } //Make framework objects available to handlers and view objects.Request.setattribute (Web_application_context_attribute, Getwebapplicationcontext ()); Request.setattribute (Locale_resolver_attribute, This. Localeresolver); Request.setattribute (Theme_resolver_attribute, This. Themeresolver); Request.setattribute (Theme_source_attribute, Getthemesource ()); Flashmap Inputflashmap= This. Flashmapmanager.retrieveandupdate (request, response); if(Inputflashmap! =NULL) {Request.setattribute (Input_flash_map_attribute, Collections.unmodifiablemap (Inputflashmap)); } request.setattribute (Output_flash_map_attribute,NewFlashmap ()); Request.setattribute (Flash_map_manager_attribute, This. Flashmapmanager); Try{dodispatch (request, response); } finally { if(Webasyncutils.getasyncmanager (Request). Isconcurrenthandlingstarted ()) {return; } //Restore The original attribute snapshot, in case of an include. if(Attributessnapshot! =NULL) {restoreattributesafterinclude (request, attributessnapshot); } } }
Three: Request distribution service. The distribution process is as follows:
1, File upload parsing, if the request type is multipart will be through the Multipartresolver file upload parsing;
2, through the handlermapping, map the request to the processor (return a handlerexecutionchain, which includes a processor, multiple handlerinterceptor interceptors);
3. Support multiple types of processors (processors in handlerexecutionchain) through Handleradapter;
4, through the Viewresolver analytic logical view name to the concrete view realization;
5, localization analysis;
6, rendering the specific views, etc.;
7, if the execution process encountered an exception will be given to Handlerexceptionresolver to resolve.
protected voidDodispatch (HttpServletRequest request, httpservletresponse response)throwsException {httpservletrequest processedrequest=request; Handlerexecutionchain Mappedhandler=NULL; Booleanmultipartrequestparsed =false; Webasyncmanager Asyncmanager=Webasyncutils.getasyncmanager (Request); Try{modelandview mv=NULL; Exception dispatchexception=NULL; Try{processedrequest=Checkmultipart (Request); Multipartrequestparsed= (Processedrequest! =request); //determine handler for the current request.Mappedhandler =gethandler (processedrequest); if(Mappedhandler = =NULL|| Mappedhandler.gethandler () = =NULL) {Nohandlerfound (processedrequest, response); return; } //determine handler adapter for the current request.Handleradapter ha =Gethandleradapter (Mappedhandler.gethandler ()); //Process last-modified Header, if supported by the handler.String method =Request.getmethod (); BooleanIsget = "GET". Equals (method); if(Isget | | "HEAD". Equals (method)) { LongLastModified =ha.getlastmodified (Request, Mappedhandler.gethandler ()); if(logger.isdebugenabled ()) {Logger.debug ("Last-modified value for [" + Getrequesturi (Request) + "] is:" +lastmodified); } if(NewServletwebrequest (Request, Response). Checknotmodified (lastmodified) &&isget) { return; } } if(!Mappedhandler.applyprehandle (processedrequest, response)) { return; } Try { //actually invoke the handler.MV =Ha.handle (processedrequest, Response, Mappedhandler.gethandler ()); } finally { if(asyncmanager.isconcurrenthandlingstarted ()) {return; }} applydefaultviewname (request, MV); Mappedhandler.applyposthandle (processedrequest, response, MV); } Catch(Exception ex) {dispatchexception=ex; } processdispatchresult (Processedrequest, Response, Mappedhandler, MV, dispatchexception); } Catch(Exception ex) {triggeraftercompletion (processedrequest, Response, Mappedhandler, ex); } Catch(Error err) {triggeraftercompletionwitherror (processedrequest, Response, Mappedhandler, err); } finally { if(asyncmanager.isconcurrenthandlingstarted ()) {//Instead of Posthandle and Aftercompletionmappedhandler.applyafterconcurrenthandlingstarted (processedrequest, response); return; } //used by a multipart request. if(multipartrequestparsed) {Cleanupmultipart (processedrequest); } } }
Go deep into Spring's web.