SPRINGMVC Source Code Analysis (next)

Source: Internet
Author: User
Tags aliases

4. Request-Process chain mapping (handlermapping)
Handlermapping defines a strategy for mapping between requests and processing chains, as shown in the following interfaces.

    Public Interface handlermapping {    = handlermapping.  Class. GetName () + ". pathwithinhandlermapping";     throws Exception;}

The main inheritance classes and inheritance structures are as follows

which
*abstracthandlermapping: Defines the most basic parts of the handlermapping implementation, including the Interceptor list and the default processing object
*abstracturlhandlermapping: On the basis of abstracthandlermapping, the mapping Relationship Management from URL to processing object is defined, and its main processing process is as follows
Gethandlerinternal:

    protectedObject gethandlerinternal (HttpServletRequest request)throwsException {String Lookuppath= This. Urlpathhelper.getlookuppathforrequest (Request); if(logger.isdebugenabled ()) {Logger.debug ("Looking up handler for [" + Lookuppath + "]"); } Object Handler=Lookuphandler (Lookuppath, request); if(Handler = =NULL) {            //we need to care for the default handler directly, since we need to//expose the Path_within_handler_mapping_attribute for it as well.Object Rawhandler =NULL; if("/". Equals (Lookuppath)) {Rawhandler=Getroothandler (); }            if(Rawhandler = =NULL) {Rawhandler=Getdefaulthandler (); }            if(Rawhandler! =NULL) {Validatehandler (rawhandler, request); Handler=Buildpathexposinghandler (Rawhandler, Lookuppath); }        }        returnhandler; }

Lookuphandler:

    protectedObject Lookuphandler (String URLPath, httpservletrequest request)throwsException {//Direct match?Object handler = This. Handlermap.get (URLPath); if(Handler! =NULL) {Validatehandler (handler, request); returnBuildpathexposinghandler (handler, URLPath); }        //Pattern match?String Bestpathmatch =NULL;  for(Iterator it = This. Handlermap.keyset (). iterator (); It.hasnext ();) {String Registeredpath=(String) it.next (); if(Getpathmatcher (). Match (Registeredpath, URLPath) &&(Bestpathmatch==NULL|| Bestpathmatch.length () <registeredpath.length ())) {Bestpathmatch=Registeredpath; }        }        if(Bestpathmatch! =NULL) {Handler= This. Handlermap.get (Bestpathmatch);            Validatehandler (handler, request); String pathwithinmapping=Getpathmatcher (). Extractpathwithinpattern (Bestpathmatch, URLPath); returnBuildpathexposinghandler (handler, pathwithinmapping); }        //No handler found ...        return NULL; }

In addition, it defines the handler registration method Registerhandler

*abstractdetectingurlhandlermapping:abstractdetectingurlhandlermapping The Applicationcontextaware interface is implemented by inheriting Applicationobjectsupport and is automatically passed after initialization is completed. Applicationobjectsupport.setapplicationcontext--> Abstractdetectingurlhandlermapping.initapplicationcontext--> Abstractdetectingurlhandlermapping.detecthandlers calls the Detecthandlers function, which checks all bean objects registered to ApplicationContext, The Determineurlsforhandler implemented by its subclasses determine the URL for each Bean object and register the URL with the bean through Abstracturlhandlermapping.registerhandler

    protected voidDetecthandlers ()throwsbeansexception {if(logger.isdebugenabled ()) {Logger.debug ("Looking for URL mappings in application context:" +Getapplicationcontext ()); } string[] Beannames= ( This. detecthandlersinancestorcontexts?beanfactoryutils.beannamesfortypeincludingancestors (Getapplicationcontext (), Object.class): Getapplicationcontext (). Getbeannamesfortype (Object.class)); //Take any bean name or alias this begins with a slash.         for(inti = 0; i < beannames.length; i++) {String beanname=Beannames[i]; String[] URLs=Determineurlsforhandler (beanname); if(!objectutils.isempty (URLs)) {                //URL Paths Found:let ' s consider it a handler.Registerhandler (URLs, beanname); }            Else {                if(logger.isdebugenabled ()) {Logger.debug ("Rejected Bean name '" + beannames[i] + "': No URL paths identified"); }            }        }    }

*beannameurlhandlermapping: Very simple, it implements the Determineurlsforhandler function, if a bean starts with a "/", it is considered a processor class, and the name of the bean is the URL of the map. The processing process is as follows

 protected   string[] Determineurlsforhandler (String beanname) {List urls  = new   ArrayList ();  if  (Beanname.startswith ("/"  = Getapplicationcontext (). getaliases (Beanname);  for  (int  j = 0; J < Aliases.length; J++ if  (Aliases[j].startswith ("/" Span style= "color: #000000;"            >)) {Urls.add (aliases[j]); }}  return   Stringutils.tostringarr    Ay (URLs); }

*defaultannotationhandlermapping: Implement the Determineurlsforhandler function, examine each Bean object's class or method there is no requestmapping this annotation, if there is , the URL of the corresponding configuration is treated as the URL for that bean, and the process is as follows

protectedstring[] Determineurlsforhandler (String beanname) {ApplicationContext context=Getapplicationcontext (); Class<?> Handlertype =Context.gettype (beanname); Requestmapping Mapping= Annotationutils.findannotation (Handlertype, requestmapping.class); if(Mapping = =NULL&& contextinstanceofConfigurableapplicationcontext &&context.containsbeandefinition (Beanname)) {configurableapplicationcontext CAC=(configurableapplicationcontext) context; Beandefinition BD=cac.getbeanfactory (). Getmergedbeandefinition (Beanname); if(BDinstanceofabstractbeandefinition) {abstractbeandefinition abd=(abstractbeandefinition) BD; if(Abd.hasbeanclass ()) {Class<?> Beanclass =Abd.getbeanclass (); Mapping= Annotationutils.findannotation (Beanclass, requestmapping.class); }            }        }        if(Mapping! =NULL) {            //@RequestMapping found at type level             This. Cachedmappings.put (handlertype, mapping); Set<String> URLs =NewLinkedhashset<string>(); String[] Paths=Mapping.value (); if(Paths.length > 0) {                //@RequestMapping Specifies paths at type level                 for(String path:paths) {addurlsforpath (URLs, path); }                returnStringutils.tostringarray (URLs); }            Else {                //actual paths specified by @RequestMapping on method level                returndetermineurlsforhandlermethods (Handlertype); }        }        Else if(Annotationutils.findannotation (Handlertype, Controller.)class) !=NULL) {            //@RequestMapping to being introspected at method level            returndetermineurlsforhandlermethods (Handlertype); }        Else {            return NULL; }    }

5. Processor Adapter (Handleradapter)
Handleradapter defines how the processing class handles the request, as shown in the following interface

    Public Interface handleradapter {    boolean  supports (Object handler);     throws Exception;     Long getlastmodified (httpservletrequest request, Object handler);}

By implementing a specific policy, you have the flexibility to convert any object into a request processing object, including the following:

1) Simplecontrollerhandleradapter/httprequesthandleradapter/simpleservlethandleradapter/throwawaycontroller
Very simple, oriented to implement the implementation of a particular interface of the processing class situation, just do a proxy execution processing, look at the simplecontrollerhandleradapter of the code below, its specific processing implements the Controller interface processing class

 Public classSimplecontrollerhandleradapterImplementsHandleradapter { Public Booleansupports (Object handler) {return(HandlerinstanceofController); }     PublicModelandview handle (httpservletrequest request, httpservletresponse response, Object handler)throwsException {return( Controller) handler). HandleRequest (request, response); }     Public Longgetlastmodified (httpservletrequest request, Object handler) {if(Handlerinstanceoflastmodified) {            return((lastmodified) handler). getlastmodified (Request); }        return-1l; }}

2) Annotationmethodhandleradapter
By configuring a specific annotation, you define how the parameters are injected, which method to invoke, and how to handle the return parameters, as follows (Annotationmethodhandleradapter.invokehandlermethod)

Try{servlethandlermethodresolver Methodresolver=Getmethodresolver (handler); Method Handlermethod=Methodresolver.resolvehandlermethod (Request); Servlethandlermethodinvoker MethodInvoker=NewServlethandlermethodinvoker (Methodresolver); Servletwebrequest webRequest=Newservletwebrequest (request, response); Extendedmodelmap Implicitmodel=NewExtendedmodelmap (); Object result=Methodinvoker.invokehandlermethod (Handlermethod, Handler, WebRequest, Implicitmodel); Modelandview Mav=Methodinvoker.getmodelandview (Handlermethod, result, Implicitmodel, webRequest); Methodinvoker.updatesessionattributes (Handler, (Mav!=NULL? Mav.getmodel ():NULL), Implicitmodel, webRequest); returnMav; }        Catch(Nosuchrequesthandlingmethodexception ex) {returnHandlenosuchrequesthandlingmethod (ex, request, response); }

*servlethandlermethodresolver (Annotationmethodhandleradapter inner Class): This class is defined by the request URL, request method, and the requestmapping of the processing class. Finally determine which method of the processing class is used to process the request
*servlethandlermethodinvoker (Annotationmethodhandleradapter inner Class): Checks the parameters of the processing class's corresponding processing method and the associated annotation configuration, Determines how the required parameters are converted into the calling method, and the final call returns Modelandview
6. View Policy (Viewresolver)
Viewresolver defines the strategy for determining the View object that handles the views, as shown in the following interface

 Public Interface viewresolver {    throws  Exception;}

SPRINGMVC Source Code Analysis (next)

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.