Deep analysis of Spring MVC principle

Posted by bdamod1 on Thu, 16 Dec 2021 13:26:51 +0100

1, spring mvc features

1. Review the servlet and jsp execution process

Process Description:

  1. Request Servlet
  2. Processing business logic
  3. Set business Model
  4. forward jsp Servlet
  5. jsp Servlet parsing encapsulates html return

2. spring mvc features:

spring mvc is essentially handled by Servlet and encapsulated on its basis, which simplifies the development process, improves ease of use, and makes the logical structure of the program clearer

  1. Annotation based URL mapping
  2. Form parameter mapping
  3. Cache processing
  4. Global unified exception handling
  5. Implementation of interceptor
  6. Download processing

3. Request processing flow

4. spring mvc example:

For ease of understanding, here is a spring mvc example with the simplest configuration:
web.xml servlet configuration:

<servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:/spring-mvc.xml
        </param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

Write Control method:

public class SimpleControl implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ModelAndView mv = new ModelAndView("/WEB-INF/page/userView.jsp");
        mv.addObject("name", "luban is good man");
        return mv;
    }
}

Configure spring MVC xml

<bean name="/hello.do" class="com.tuling.control.SimpleControl"/>
  • Perform test demonstration:

How is the whole process realized?

  1. How does the dispatchServlet find the corresponding Control?
  2. How to execute and call business methods in Control?

In order to answer the above questions in the interview, we must understand the system composition of spring mvc.

2, Detailed explanation of mvc architecture

Problems solved by spring mvc framework

From a technical point of view, any existing framework has its reason for existence, and this reason is to solve practical problems. Or provide a better solution to the problem. spring mvc what problems does it solve?

  1. URL mapping
  2. Form parameter mapping
  3. Call target Control
  4. Data model mapping
  5. View resolution
  6. exception handling

The above technical solutions are embodied in the following components in spring mvc

  • HandlerMapping 'hændlə 'mæpɪŋ
    • url and controller mapping
  • HandlerAdapter 'hændlə ə'dæptə
    • Controller execution adapter
  • ViewResolver vjuː riː'zɒlvə
    • View warehouse
  • view
    • Specific analysis view
  • HandlerExceptionResolver 'hændlə ɪk'sepʃ(ə)n riː'zɒlvə
    • Anomaly catcher
  • HandlerInterceptor 'hændlə ɪntə'septə
    • Interceptor

The corresponding uml is shown in the figure below:

mvc component execution process

HandlerMapping details

It is the mapping between url path and Control object in mvc. Dispatcher servlet is based on this component to find the corresponding Control. If it cannot be found, it will report an exception of No mapping found for HTTP request with URI.

HandlerMapping interface structure analysis:

HandlerMapping is used to find the corresponding handler through the url, but its HandlerMapping The gethandler () method does not directly return the handler object, but returns the HandlerExecutionChain object through HandlerExecutionChain Gethandler () returns the final handler

Common implementation classes:

The three mainstream mapping methods are as follows:

  1. SimpleUrlHandlerMapping: Based on manually configured url and control mapping
  2. BeanNameUrlHandlerMapping: register to Yingxie based on the Bean time line beginning with "/" in ioc name
  3. RequestMappingHandlerMapping: configure mapping based on @ RequestMapping annotation

SimpleUrlHandlerMapping
Demonstrates configuring mappings based on simpleurhandlermapping.
Write mvc file

<!--Simple controller-->
<bean name="simpleControl" class="com.tuling.control.SimpleControl"/>
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="urlMap">
        <props>
            <prop key="/hello.do">
                simpleControl
            </prop>
        </props>
    </property>
</bean>

SimpleUrlHandlerMapping architecture:

Key source code for initializing simpleurhandlermapping process:

>org.springframework.web.servlet.handler.SimpleUrlHandlerMapping#setUrlMap
>org.springframework.web.servlet.handler.SimpleUrlHandlerMapping#initApplicationContext
>org.springframework.web.servlet.handler.SimpleUrlHandlerMapping#registerHandlers
>org.springframework.web.servlet.handler.AbstractUrlHandlerMapping#registerHandler() / / / indicates the root path / * indicates the default path

Get the key source code of Handler process:

>org.springframework.web.servlet.DispatcherServlet#doService
>org.springframework.web.servlet.DispatcherServlet#doDispatch
>org.springframework.web.servlet.DispatcherServlet#getHandler
>org.springframework.web.servlet.handler.AbstractHandlerMapping#getHandler
>org.springframework.web.servlet.handler.AbstractUrlHandlerMapping#getHandlerInternal
>org.springframework.web.util.UrlPathHelper#getPathWithinApplication / / get the URL path
>org.springframework.web.servlet.handler.AbstractUrlHandlerMapping#lookupHandler / / find handler
>org.springframework.web.servlet.handler.AbstractHandlerMapping#getHandlerExecutionChain / / encapsulates the execution chain

BeanNameUrlHandlerMapping

The implementation of BeanNameUrlHandlerMapping is consistent with SimpleUrlHandlerMapping. The only difference is that it inherits from AbstractDetectingUrlHandlerMapping. The url and handler mapping can be found without configuration through the corresponding detectHandlers.
Structure diagram:

RequestMappingHandlerMapping
It is implemented based on annotations, which will be explained in detail when explaining annotation reflection and appreciation in subsequent chapters.

Handler type
In AbstractUrlHandlerMapping, we can see that the Map value type of Handler is Object. Does that mean that all classes can be used as handlers?

The corresponding types of Handler are as follows:

  • Controller interface:
  • HttpRequestHandler interface:
  • HttpServlet interface:
  • @RequestMapping method annotation

It can be seen that there is no unified interface for the handler. How to call it after the dispatchServlet obtains the corresponding handler? Which method is called? There are two ways to solve this problem. One is to use instanceof to determine the type of Handler and then call the related methods. The second is through the introduction of adapters, and each adapter implements the call to the specified handler. spring adopts the latter.

HandlerAdapter details

Here, spring mvc uses the Adapter mode to adapt and call the specified Handler. Different adapters are used according to different types of handlers. The corresponding relationship between the Handler and the HandlerAdapter is as follows:

Handler classCorresponding adapterdescribe
ControllerSimpleControllerHandlerAdapterStandard controller, return ModelAndView
HttpRequestHandlerHttpRequestHandlerAdapterThe business processes the request by itself and does not need to go to the view through modelAndView
ServletSimpleServletHandlerAdapterStandard based servlet processing
HandlerMethodRequestMappingHandlerAdapterProcessing method based on @ requestMapping

HandlerAdapter interface method

HandlerAdapter interface structure diagram

  • Demonstrate Servlet based processing of SimpleServletHandlerAdapter
<!-- Configuration controller -->
<bean id="/hello.do" class="com.tuling.mvc.control.HelloServlet"/>

<!-- Configure adapter -->
<bean class="org.springframework.web.servlet.handler.SimpleServletHandlerAdapter"/>
// Standard Servlet
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().println("hello luban ");
    }
}

In the above example, when these classes are instantiated in the IOC, the DispatcherServlet will pass
org. springframework. web. servlet. The dispatcherservlet#gethandleradapter() method looks for the adapter of the corresponding handler. If it cannot be found, the following exception will be reported.

>javax.servlet.ServletException: No adapter for handler [com.tuling.control.SimpleControl@3c06b5d5]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler
>org.springframework.web.servlet.DispatcherServlet.getHandlerAdapter(DispatcherServlet.java:1198)
>org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)

ViewResolver and View details

After finding the appropriate Adapter, the business processing will be called based on the Adapter. After processing, the business party will return a ModelAndView to find the corresponding view for processing. It's on org springframework. web. servlet. In dispatcherservlet #resolveviewname(), traverse the viewResolvers list to find it. If it cannot be found, a Could not resolve view with name exception will be reported.

BeanNameViewREsolver example:
Add custom view:

public class MyView implements View {
    @Override
    public void render(Map<String, ?> model, HttpServletRequest 
            request, HttpServletResponse response) throws Exception {
        response.getWriter().print("hello luban good man.");
    }
}

To configure the view parser:

<bean name="myView" class="com.tuling.control.MyView"/>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>

Modify view jump method:

public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
    ModelAndView mv = new ModelAndView("myView");
    mv.addObject("name", "luban is good man");
    return mv;
}

InternalResourceViewResolver example:

<!--Resource parser -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/page/"/>
    <property name="suffix" value=".jsp"/>
    <property name="viewClass" value="org.springframework.web.servlet.view.InternalResourceView"/>
</bean>

The next step is based on viewresolver Resolveviewname() gets the corresponding view to parse, generate Html and return. The corresponding view structure is as follows:

Topics: Spring Interview mvc