Requestmappinghandlermapping: This handlermapping is an annotation-based
Similarly, first the class diagram:
As can be seen through the class diagram, the same is inherited from the parent class abstracthandlermapping to do the initialization of the interceptor, actually dealing with their own logic only the following three classes;
It is important to note that Requestmappinghandlermapping initialization is not a rewrite of the Initapplicationcontext () method, but rather the initial work by implementing the Initializingbean interface.
Note: The Initializingbean interface provides a way for the bean to initialize the method, which includes only the Afterpropertiesset method, and the class that implements the interface, which executes the method when the bean is initialized.
Look at the key code in abstracthandlermethodmapping:
1 Public voidAfterpropertiesset () {///implements the Initializingbean interface method to initialize the entry. 2 This. Inithandlermethods ();3 }4 5 protected voidInithandlermethods () {6 if( This. logger.isdebugenabled ()) {7 This. Logger.debug ("looking for request mappings in application context:"+ This. Getapplicationcontext ());8 }9Scan all object classes under ApplicationTenstring[] Beannames = This. detecthandlermethodsinancestorcontexts? Beanfactoryutils.beannamesfortypeincludingancestors ( This. Getapplicationcontext (), Object.class) : This. Getapplicationcontext (). Getbeannamesfortype (Object.class); Onestring[] arr$ =Beannames; A intlen$ =beannames.length; - - for(inti$ =0; i$ < len$; ++i$) { theString Beanname =arr$[i$]; - if( This. Ishandler ( This. Getapplicationcontext (). GetType (Beanname))) {//ishandler is implemented by subclasses and is a hook method that allows subclasses to implement their own logic - This. Detecthandlermethods (beanname); - } + } - + This. handlermethodsinitialized ( This. Gethandlermethods ());//Initialize the Processor object, currently the hook method, but there is no subclass to implement this method A}
The Ishandler method is implemented in the Requestmappinghandlermapping
1 protected Boolean ishandler (class<?> beantype) {//very simple to see if this class has no controller or requestmapping annotations, There is one on line 2 return annotationutils.findannotation (Beantype, Controller. Classnull | | Annotationutils.findannotation (Beantype, requestmapping. Classnull; 3 }
Back to Abstracthandlermethodmapping look:
1 protected voidDetecthandlermethods (Object handler) {//Start registration Handler2Class<?> Handlertype = Handler instanceof String? This. Getapplicationcontext (). GetType ((String) handler): Handler.getclass ();3Final class<?> usertype =Classutils.getuserclass (Handlertype);
This is all the way to get HANDELR, but there is a filter that gets the method with the matching criteria4Set<method> methods = Handlermethodselector.selectmethods (usertype,NewMethodfilter () {5 PublicBoolean Matches (method) {6 returnAbstracthandlermethodmapping. This. Getmappingformethod (method, usertype)! =NULL;//getmappingformethod Hook method, sub-class implementation7 }8 });9Iterator i$ =methods.iterator ();TenTraverse method to register. One while(I$.hasnext ()) { AMethod method =(Method) I$.next (); -T mapping = This. Getmappingformethod (method, usertype); - This. Registerhandlermethod (Handler, method, mapping); the } - -}
To see the realization of Getmappingformethod, is realized in requestmappinghandlermapping
1 protectedRequestmappinginfo Getmappingformethod (method, class<?>Handlertype) { 2Requestmappinginfo info =NULL;//Get the requestmapping annotation information on the method3Requestmapping methodannotation = (requestmapping) annotationutils.findannotation (method, requestmapping.class);4 if(Methodannotation! =NULL) {5Requestcondition<?> methodcondition = This. Getcustommethodcondition (method);6info = This. Createrequestmappinginfo (Methodannotation, methodcondition); Construction matching conditions
Get Polygon requesthandlermapping annotation information on a class7Requestmapping typeannotation = (requestmapping) annotationutils.findannotation (Handlertype, RequestMapping.class);8 if(Typeannotation! =NULL) {9Requestcondition<?> typecondition = This. Getcustomtypecondition (handlertype);Teninfo = This. Createrequestmappinginfo (Typeannotation, typecondition). Combine (info); construct matching conditions, merge with method One } A } - - returninfo; the}
notes under ; Requestmappinginfo is actually an abstract object that matches the condition, including the url,method,param,header ... Wait a minute
Look at how the processor is stored before looking at the registration method;
1 Public Abstract class Abstracthandlermethodmapping<t> extends abstracthandlermapping implements Initializingbean {2 //This block is actually saved by two maps, generics are actually requestmappinginfo, this is the match condition Hanldermethod is the encapsulation class that encapsulates all the information of the processor
3 Private New Linkedhashmap ();///Save is key: Match condition value: Processor 4 Private New Linkedmultivaluemap (); Key:url Value: Match condition
This piece is about Multivaluemap.
Public interface multivaluemap<k, v> extends Map<k, list<v>>//is actually a Map of value is a List
1 protected voidRegisterhandlermethod (Object handler, method, T mapping) {2 Handlermethod Handlermethod;3 if(Handler instanceof String) {4String Beanname =(String) handler;5Handlermethod =NewHandlermethod (Beanname, This. Getapplicationcontext (), method);6}Else {7Handlermethod =NewHandlermethod (handler, method);8 }9 TenHandlermethod Oldhandlermethod = (handlermethod) This. Handlermethods.Get(mapping); One if(Oldhandlermethod! =NULL&&!oldhandlermethod.equals (Handlermethod)) {//does not allow one mapping to correspond to multiple Handlermethod A Throw NewIllegalStateException ("ambiguous mapping found. Cannot map '"+ Handlermethod.getbean () +"' Bean method \ n"+ Handlermethod +"\nto"+ Mapping +": There is already '"+ Oldhandlermethod.getbean () +"' Bean method\n"+ Oldhandlermethod +"mapped."); -}Else { - This. Handlermethods.put (mapping, handlermethod);//Storage of the first set of mappings the if( This. logger.isinfoenabled ()) { - This. Logger.info ("Mapped \ ""+ Mapping +"\ "onto"+Handlermethod); - } - +set<string> patterns = This. Getmappingpathpatterns (mapping);//Gets the URL of the method -Iterator i$ =patterns.iterator (); + A while(I$.hasnext ()) { atString pattern =(String) I$.next (); - if(! This. Getpathmatcher (). Ispattern (pattern)) {//Put in a second map collection - This. Urlmap.add (pattern, mapping); - } - } - in } -}
At this end, Requestmappinghandlermapping is initialized.
Question: Why are non-annotation mappers overridden by overriding the InitApplication method, while the annotation mapper is initialized by implementing the Iniliazingbean interface, what are the benefits?
Welcome to Explore
Spring MVC's handlermapping requestmappinghandlermapping initialization