Springmvc source code interpretation of the Handlermapping_java

Source: Internet
Author: User
Tags inheritance prepare

Overview

For web developers, the MVC model is all the more familiar, in Springmvc, a request to meet the requirements enters the dispatcherservlet responsible for the request for distribution, Dispatcherservlet according to the request URL to the controller's mapping (save in Handlermapping), Handlermapping eventually returns to Handlerexecutionchain, It contains the specific processing object handler (also known as our programming Controller) and a series of interceptor interceptors, At this point Dispatcherservlet will find an adapter (Handleradapter) that supports this processor type based on the handler in the returned Handlerexecutionchain. In the processor adapter, the controller's request response method is eventually invoked and the result view (Modelandview) is returned, and the results are displayed through the Render method after the result view is obtained.

Handermapping's Inheritance system:

SPRINGMVC is resolved through the Handlermapping module in the request to the handler processor distribution. Handlermapping also handles interceptors.

Let's take a look at Handlermapping's inheritance tree.

You can do this sort of thing roughly:

1. An interface handlermapping, defining a Api:handlerexecutionchain gethandler (HttpServletRequest request) throws Exception;

2. A basic abstract class: The main is to prepare context environment, provide gethandlerinternal hook, encapsulation interceptor to Handlerexecutionchain

3. Based on annotation @controller, the use of @RequestMapping

4. Configure the URL directly in the configuration file to handler simpleurlhandlermapping

5. Default implementation beannameurlhandlermapping

6. Mapping of controller subclasses

Look at the handlermapping, just a GetHandler API is very simple.

Handlermapping
package org.springframework.web.servlet;
Public interface Handlermapping {
handlerexecutionchain gethandler (HttpServletRequest request) throws Exception;
}

Abstracthandlermapping's not that simple.

First look at the abstracthandlermapping inherited classes, the implementation of the interface

Package Org.springframework.web.servlet.handler;
Public abstract class Abstracthandlermapping extends Webapplicationobjectsupport
implements Handlermapping, Ordered {
//...
}

Webapplicationobjectsupport is used to provide context ApplicationContext and ServletContext.

There is also the Initapplicationcontext method, often used in the follow-up. The abstracthandlermapping directly covered it.

The Applicationcontextaware and Servletcontextaware interfaces are implemented in the parent class, and the spring concept is very unified.

Ordered is used for collection sorting.

And then look at Abstracthandlermapping's properties.

Abstracthandlermapping
//order has the maximum value, the priority is the smallest
private int order = Integer.max_value;//Default:same as Non-or dered
//default handler, this side of the use of OBEJCT, subclass implementation, the use of handlermethod,handlerexecutionchain, such as
private Object DefaultHandler;
Helper class for URL computing
private urlpathhelper urlpathhelper = new Urlpathhelper ();
Path matching based on ant to resolve such as/books/{id} scene
private pathmatcher pathmatcher = new Antpathmatcher ();
Interceptor configuration:, Handlermapping property settings, Extendinterceptors set
private final list<object> interceptors = new ArrayList <Object> ();
From interceptors, directly add to all handler
private final list 
 

Look at the initialization of the Interceptor:

abstracthandlermapping @Override protected void Initapplicationcontext () throws Beansexception {extendinterceptors (
This.interceptors);
Detectmappedinterceptors (this.mappedinterceptors);
Initinterceptors (); /** * provided to subclass extension interceptors, unfortunately none of the interceptors under the * * protected void Extendinterceptors (List<object>/**) {} Mappedint * Scan application Erceptor and added to Mappedinterceptors * * protected void detectmappedinterceptors (list<mappedinterceptor>
mappedinterceptors) {Mappedinterceptors.addall (beanfactoryutils.beansoftypeincludingancestors) (
Getapplicationcontext (), Mappedinterceptor.class, True, false). values ()); /** * Collect mappedinterceptor and fit Handlerinterceptor and webrequestinterceptor/protected void initinterceptors () {if (!this . Interceptors.isempty ()) {for (int i =; I < this.interceptors.size (); i++) {Object Interceptor = THIS.INTERCEPTORS.G
ET (i);
if (Interceptor = = null) {throw new IllegalArgumentException ("Entry number" + i + "in interceptors array is null");} if (Interceptor InstanCeof mappedinterceptor) {Mappedinterceptors.add ((mappedinterceptor) interceptor);} else {Adaptedinterceptors.add (
Adaptinterceptor (Interceptor));  }}} protected Handlerinterceptor Adaptinterceptor (Object Interceptor) {if (Interceptor instanceof Handlerinterceptor) {return (handlerinterceptor) Interceptor} else if (Interceptor instanceof Webrequestinterceptor) {return new Webreque
Sthandlerinterceptoradapter ((Webrequestinterceptor) interceptor); else {throw new IllegalArgumentException ("Interceptor type not supported:" + Interceptor.getclass (). GetName ());}

Then is the implementation of GetHandler (HttpServletRequest request), while reserving gethandlerinternal (HttpServletRequest request) to implement the subclass

Abstracthandlermapping public
Final Handlerexecutionchain gethandler (HttpServletRequest request) throws Exception {
Object handler = gethandlerinternal (request);
if (handler = = null) {
handler = Getdefaulthandler ();
}
if (handler = = null) {return
null;
}
Bean name or resolved handler?
if (handler instanceof string) {
string handlerName = (string) handler;
Handler = Getapplicationcontext (). Getbean (handlerName);
Return Gethandlerexecutionchain (handler, request);
}

And finally, the encapsulation interceptor to Handlerexecutionchain.

Adaptedinterceptors Add directly

Mappedinterceptors need to be added based on URL matching

abstracthandlermapping
protected Handlerexecutionchain gethandlerexecutionchain (Object handler, HttpServletRequest request) {
Handlerexecutionchain chain =
(handler instanceof handlerexecutionchain)?
(Handlerexecutionchain) Handler:new Handlerexecutionchain (handler);
Chain.addinterceptors (Getadaptedinterceptors ());
String Lookuppath = urlpathhelper.getlookuppathforrequest (request);
for (Mappedinterceptor mappedinterceptor:mappedinterceptors) {
if mappedinterceptor.matches (LookupPath, Pathmatcher)) {
chain.addinterceptor (Mappedinterceptor.getinterceptor ());
}
}
return chain;

Controller The mapping of subclasses, this branch first looks at class inheritance

Let's talk about the main responsibilities of each class here.

1. abstracthandlermapping prepare the context environment; provide gethandlerinternal hooks; encapsulate interceptors to Handlerexecutionchain

2. Abstracturlhandlermapping implements the registration handler method for the subclass to use, realizes Gethandlerinternal, finds the handler by the child class initialization configuration information,

3. Abstractdetectingurlhandlermapping scanning application of the object, after the iteration to provide a hook method Determineurlsforhandler the subclass determines how to filter

4. Abstractcontrollerurlhandlermapping implementation Determineurlsforhandler, add filtering to exclude the handler operation (configuration file configuration), The reservation hook method is buildurlsforhandler to the subclass, and the subclass of Controller is also judged.

5. Controllerbeannamehandlermapping generates URLs based on Bean name

Controllerclassnamehandlermapping generates URLs based on class name

From the abstracturlhandlermapping start to see, this is just a general look at the code, if you need to carefully analyze, please step <springmvc source Interpretation-handlermapping- Abstracturlhandlermapping Series Request Distribution >

Registration of Handler

protected void Registerhandler (string[] urlpaths, String beanname) throws Beansexception, IllegalStateException {}

Search for Handler

Protected Object gethandlerinternal (HttpServletRequest request) throws Exception {}
//lookup based on URL handler
Protected Object Lookuphandler (String URLPath, httpservletrequest request) throws Exception {}
//checksum handler
protected void Validatehandler (Object handler, HttpServletRequest request) throws Exception {}
// Encapsulates the interceptor to the Handlerexecutionchain
protected Object Buildpathexposinghandler (object Rawhandler, String Bestmatchingpattern,
String pathwithinmapping, map<string, string> uritemplatevariables) {} 

Abstractdetectingurlhandlermapping, this side does not unfold, specific step <springmvc source interpretation-handlermapping- Abstractdetectingurlhandlermapping Series Initialization >

Specific things to do:

1. Call Detecthandlers scan obejct by overwrite Initapplicationcontext

2. Provide hook method Determineurlsforhandler to subclass to generate URL based on handler

3. Invoke the Registerhandler of the parent class for registration

@Override public
void Initapplicationcontext () throws Applicationcontextexception {
Super.initapplicationcontext ();
Detecthandlers ();
}
protected void Detecthandlers () throws Beansexception {
//...
}
/**
* Determine the URL for the given handler Bean.
* Hook just * *
protected abstract string[] Determineurlsforhandler (String beanname); 

Abstractcontrollerurlhandlermapping, this side does not unfold, specific step <springmvc source interpretation-handlermapping- Abstractdetectingurlhandlermapping Series Initialization >

To do something specifically;

1. Overwrite Determineurlsforhandler Add the logic of culling part class, excludedclasses and Excludedpackages are used here through configuration file configuration.

2. To determine whether the controller of the subclass

3. Reserve Buildurlsforhandler to generate URLs for subclasses

@Override
protected string[] Determineurlsforhandler (String beanname) {
Class Beanclass = Getapplicationcontext (). GetType (beanname);
if (iseligibleformapping (Beanname, Beanclass)) {return
Buildurlsforhandler (Beanname, Beanclass);
}
else {return
null;
}
}
Protected Boolean iseligibleformapping (String beanname, Class beanclass) {}
protected Boolean iscontrollertype ( Class Beanclass) {}
protected abstract string[] Buildurlsforhandler (String beanname, Class beanclass); 

Controllerbeannamehandlermapping and controllerclassnamehandlermapping directly look at the source, or <springmvc source code interpretation-HandlerMapping- Abstractdetectingurlhandlermapping Series Initialization >

Configuration file directly configure the URL to handler simpleurlhandlermapping, is to use the Registerhandlers registration configuration document handler, directly to see the code or to the <springmvc source interpretation- Handlermapping-simpleurlhandlermapping initialization >

Beannameurlhandlermapping implementation Determineurlsforhandler generate URLs, directly look at the code or <SPRINGMVC source interpretation-handlermapping- Abstractdetectingurlhandlermapping Series Initialization >

Based on annotation @controller, the use of @RequestMapping

The hardest bone to utter

Let's look at class inheritance.

The responsibility of each class, the specific analysis or to the following article

<springmvc Source code Interpretation-Handlermapping-requestmappinghandlermapping initialization >

<springmvc Source code Interpretation-Handlermapping-requestmappinghandlermapping Request Distribution >

  1. abstracthandlermethodmaping defines the initialization process and how the request is mapped

Class

Object under the 1.1.1 Scan application

1.1.2 Reserve Ishandler Hook method to determine whether object handler

1.1.3 Iterative scanning every handler, find the way to meet the requirements, this side of the judgment is still left to subclass implementation Getmappingformethod

1.1.4 registers a found processor, you need to ensure that a matching condition requestmappinginfo can only be mapped to a handler

1.1.5 according to matching criteria to get the URL, the same is just define the process, the specific algorithm for the implementation of the subclass Getmappingpathpatterns

Requesting Request distribution processing:

1.2.1 Direct string matching way to find handler

1.2.2 Matching Criteria lookup, the specific algorithm is referred to the subclass processing getmatchingmapping

1.2.3 sort and get the best match handler, this side of the sorting method or subclass processing Getmappingconmparator

1.2.4, respectively, to encapsulate matched and mismatched to handler

  2. Requestmappinginfohandlermapping uses Requestmappinginfo to implement matching criteria, Requestmappinginfo initialization is left to subclasses

2.1 Generate URLs based on Requestmappinginfo->getmappingpathpatterns

2.2 Using matching criteria to find handler-> getmatchingmapping

2.3 Completion of the comparator algorithm-> Getmappingcomparator

2.4 Overwrite Handlematch, cache n more information to request

Registration pattern, the pattern,url of the best match, the parameters parsed in the URL, the multivalued parameters parsed in the URLs, mediatype

2.1.5 Handlernomatch, the last struggle, and then try to match again

  3. requestmappinghandlermapping generates Requestmappinginfo according to the annotation @controller @RequestMapping and verifies Ishandler

3.1 Overwrite afterpropertiesset, add file suffix to judge

3.2 Implement Ishandler, there are @controller on the class @RequestMapping one of the annotations on the

3.3 Analysis of annotation content, production Requestmappinginfo instance

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.