What is the relationship between SpringMVC and Spring?

Author: Zhuangsheng Wen
link: https: //www.zhihu.com/question/39678061/answer/312545961
Source: know almost
copyrighted by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

Basic Process of Spring Web Framework

Know the Spring MVC framework, now let's take a look at its process

The Spring MVC Framework is as large as the process: When the web program starts, ContextLoaderServlet will read the corresponding configuration file information, and initialize the controller DispatchServlet through injection. When an HTTP request is received, DispatchServlet will let HandlerMapping go Handle this request. HandlerMapping selects a Controller according to the request URL (not necessarily a URL, it can be customized, very flexible). Then DispatchServlet will call the handlerRequest method of the selected Controller, and call the Controller before and after this method interceptor (if configured), and then return a collection of views and models ModelAndView. The framework resolves the view through ViewResolver and returns a View object, and finally calls the render method of View to return to the client

DispatcherServlet

This is the controller of the framework, which is a concrete class, which is initialized by the context object at runtime. The controller itself does not control the process, but is just the "controller" of the Controller. It just delegates the responsibility of processing the request to The corresponding Controller. The
controller inherits from the abstract base class FrameworkServlet, and its attribute webApplicationContext represents the web program context, and the default implementation of this context object is to read configuration information from an XML file (of course, it can also be in other file formats) . WebApplicationContext is actually the beans package. This package provides the basic structure of the entire Spring framework. I will analyze the content of this package in the future. But now I only need to know that WebApplicationContext represents the context object of a web application.

Now let's see how DispatchServlet works:

DispatchServlet inherits from the abstract base class FrameworkServlet, and the doGet() and doPost() methods in FrameworkServlet call serviceWrapper(), jump to serviceWrapper() to see, it turns out that it has delegated the specific implementation to doService(request) , response); method. So it is now clear that DispatchServlet really implements the function of the doService() method.
In particular, the initFrameworkServlet() method of FrameworkServlet is the initialization method of the controller, used to initialize objects such as HandlerMappings , This is also delayed to the implementation of the subclass. In fact, it is an implementation of the Template pattern. Don't call us, we will call u. In general, Spring implements its inversion of control in this way: use the framework to Control the flow, not the user

Jump to doService() and take a look, you will find that it is another helper function doDispatch(request, response) that really works. There is no way, continue to read and find these two lines of code

HandlerExecutionChain mappedHandler = null;
mappedHandler = getHandler(processedRequest, false);

Looking at the source code of HandlerExecutionChain, it turns out that it actually wraps the Controller and its Interceptors;

getHandler() is to retrieve the corresponding handlerMapping object from HandlerMappings (this is a List, stored handlerMapping objects), each HandlerMapping object represents a Controller and URL mapping (in fact, at runtime, it is a HandlerExecutionChain and URL mapping, and The HandlerExecutionChain object is actually a wrapper for the Controller and its interceptors. HandlerMapping can be regarded as a mapping between Controller and URL). This HandlerMapping is injected at runtime through the configuration file. Generally, the SimpleUrlHandlerMapping subclass
obtains the HandlerMapping object. , Continue to look down and find:

if(mappedHandler.getInterceptors()!=null)

    {
    
    
        for (int i = 0; i < mappedHandler.getInterceptors().length; i++) {
    
    
            HandlerInterceptor interceptor = mappedHandler.getInterceptors()[i];
            if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {
    
    
                triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);
                return;
            }
            interceptorIndex = i;
        }
    }

Here is the interceptor that is calling the Controller, the principle is this sentence:

interceptor.preHandle(processedRequest, response,mappedHandler.getHandler(), mv);

The preHandle method passes in the mappedHandler.getHandler() parameter to implement recursive calls! The interceptor.postHandle method is so general. It's just that this method is called after the handleRequest method

Keep reading:

HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); 
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

It is found that the real operation of Controller's handleRequest is delegated to the handle method of HandlerAdapter, and a ModelAndView is returned. I think the meaning of adding a layer here should be to decouple the Controller and DispatchServlet.

Then it's very simple, call the render() method, in this method, ViewResoler parses out the view name, and then call the render method of the view object to show the appropriate view to the user

At this point, the process of the controller is over

HandlerMapping

By using HandlerMapping, the controller can use the URL to perform a standard mapping with a Controller, and realize the UrlHandlerMapping of the specific subclass of URL mapping.

Spring also allows us to customize the mapping, such as mapping by Session, cookie or user state. And all this only needs to implement the HandlerMapping interface. But URL mapping can already meet most of the requirements

Controller

Controller is similar to Structs Action. The Controller interface has only one method handleRequest(), which puts back a ModelAndView object. As the design goal said, each Controller is a java component, so it can be arbitrarily configured in the context, component properties Will be configured during initialization. Spring provides several specific implementations. It is convenient for us to use

ViewResolver

Controller usually returns a ModelAndView object that contains the name of the view instead of the view object. This completely removes the coupling relationship between the controller and the view, and can also provide internationalization support here. In your configuration file you can:

welcomeView.class = org.springframework.web.servlet.view.InternalResourceView
welcomeView.url=/welcome.jsp
也可以
welcomeView.class = org.springframework.web.servlet.view.xslt.XsltView
welcomeView.url=/xslt/default.xslt

View

This is also a java component. It does not do any request processing or business logic. It only obtains the data passed by the model and displays the data. The render method in it works according to the following process:

  1. Set the data of the model to the request scope
  2. Get the URL of the view
  3. Forward to the corresponding URL

Guess you like

Origin blog.csdn.net/qq1350975694/article/details/108735186