Principle Analysis of SpringMVC Components

Principle Analysis of SpringMVC Components

Mainly analyze the process of DispatcherServlet (front controller) initialization, and DispatcherServlet executes the main process

1. Front-end controller initialization

DispatcherServlet initialization does two things

  • Obtained a SpringMVC ApplicationContext container
  • Registered nine components of SpringMVC

image-20230613111658664

1.1 Initialize the SpringMVC container

The front controller DispatcherServlet is the entrance of SpringMVC and the brain of SpringMVC, where the work of the main process is completed

DispatcherServlet is essentially a Servlet. When load-on-startup is configured, the creation and initialization init method will be executed when the server starts, and the service method will be executed for each request.

Look for the init method, and find that there is no DispatcherServlet class, so go to his father, FrameworkServlet class, and there is no father, so keep looking until there is an init method in the HttpServletBean class

Find the init method, see that an initServletBean method is called, click to see

image-20230613112755961

The initServletBean method is as follows, and there is nothing found, indicating that it is implemented by a subclass, that is, the FrameworkServlet class

image-20230613112837298

Find the initServletBean method in the FrameworkServlet class, and then find the following statement to get the Spring container in the web environment

image-20230613113105857

Click to have a look and find that a Spring container has been created

image-20230613113321181

Still in this method, look down and put the reference of the Spring container as a parameter in the following method

What is the effect of passing in the Spring container?

​ Set the reference of the Spring container as a property of SpringMVC, through this place to reflect the relationship of a parent-child container

image-20230613113849406

What does the parent-child container do?

When SpringMVC acquires Bean, it will first obtain it from its own container. If it does not have its own container, it will use parent to find the parent container, which is the Spring container, and then check whether there is a corresponding Bean from inside.

Can Spring get the Bean in SpringMVC?

No, because SpringMVC is a sub-container

image-20230613113637730

1.2 Registered nine components of SpringMVC

Not too often understand 141-SpringMVC Framework-Component Principle Analysis-Front Controller Initialization-Registration of Nine Major Components_哔哩哔哩_bilibili

When we create the SpringMVC container, we will execute the statement marked in red below

configureAndRefreshWebApplicationContext, configure and refresh the SpringMVC container

image-20230613142735169

Go ahead and create if not

image-20230613142943775

Click the method in the above picture, and click until the picture below

Found that there is also a call to the configureAndRefreshWebApplicationContext method

image-20230613143105849

After the above two processes, whether it is a newly created SpringMVC container or only an existing SpringMVC container, the configureAndRefreshWebApplicationContext method will be executed




Click into the method configureAndRefreshWebApplicationContext

Found that there is a refresh method in this method

image-20230613144309374

Click into the refresh method and find that a finishRefresh method is finally called to complete the refresh

image-20230613144532690

Click into the finishRefresh method to have a look, an event is published in this method

We set this event, and the listeners corresponding to the event will be executed.

image-20230613144648104




Go back to the FrameworkServlet class at this point

Find the following method, which is a listener. The listener is the generic ContextRefreshedEvent, which is the type of event we publish (above)

This FrameworkServlet.this.onApplicationEvent(event); code will execute

Why is it enforced?

在另一个地方会发布事件

image-20230613145827973

​ Among them, there is a listener in the FrameworkServlet class that listens to the above events

After listening to this FrameworkServlet.this.onApplicationEvent(event); the code will be executed

image-20230613145140415

Look at the onApplicationEvent method , there is an onRefresh method inside,

image-20230613150017954

Look at the onRefresh method , but nothing is written inside, indicating that it is implemented by subclasses

image-20230613150131943

Look at the onRefresh method in the DispatcherServlet class, a subclass of the FrameworkServlet class

image-20230613150304968

Finally, register the nine components of SpringMVC

image-20230613142408326

1.3 Processor mapper initialization details

Registered nine components, we can choose a familiar initHandlerMappings to view

The operation of this step is to see if there is a component of type HandlerMapping in the Spring container. If so, the matchingBeans parameter is not empty.

image-20230613152129792

Then you can't enter the following if judgment at this time, and the components in the default configuration file will not be loaded

image-20230613152446708

After the break point, why are there four parameters of the HandlerMapping type?

image-20230613154805606

We previously configured an annotation @EnableWebMVC

image-20230613154946059

Or in the spring-mvc.xml file

image-20230613155036478

There are many functions of MVC annotation driver, which will help us inject some components into SpringMVC, where HandlerMapping is registered

The operations of the above sentences are all done by @EnableWebMVC annotation for us

If we comment out the @EnableWebMVC annotation, the size of the matchingBeans parameter is 0, and the components in the default configuration file will eventually be loaded, which is framed in the following figure

image-20230613155451134

Four HandlerMapping type components, let's click to see one

But we only manually configured one interceptor, why are two shown?

Spring itself provides two

image-20230613160242152

Look at the MappingRegistery parameter again

image-20230613160549789

Just click in and have a look

image-20230613160706069

2. The front-end controller executes the main process

When the server starts, DispatcherServlet will perform the initialization operation. Next, each visit will execute the service method . Let's take a macro look at the execution process and study the source code and component execution details.

image-20230613162624565

2.1 Locating the doDispatcher method

Find the service method in the DispatcherServlet class, but there is no one, then find his father FrameworkServlet class, and find that there is a Service method, but this method is not the most original method, the most original method is the ServletRequest parameter

image-20230613163345862

Look for the HttpServletBean class of the FrameworkServlet class, but there is no Service method

Look for the HttpServlet class again, and find that there is a Service method, and it is native (there is no http in front of the parameter)

image-20230613164011177

The service method in the above figure calls the following service method (this service is overloaded)

Internally, according to the request method, see whether to call dopost or doGet

image-20230613164605139

We can look at the doPost method, but there is a small sign on the left of this method, indicating that it has been overridden by a subclass

image-20230613164726841

Click the small sign, then enter the FrameworkServlet class, and see the doPost method

image-20230613164845841

A processRequest method is called in the doPost method

image-20230613164951983

The doService method is called in the processRequest method, but we found that doService is an abstract method, we need to find the corresponding implementation

image-20230613165032250

Take a look at the specific implementation of the doService abstract method, and you will arrive at the DispatcherServlet class

Another method doDispatch is called in the doService method

image-20230613165654298

Take a look at the doDispatch method, the core main process is here

2.2 Verify HandlerExecutionChain

Start looking for doDispatch in the DispatcherServlet class

There is a parameter HandlerExecutionChain in this method, which includes Interceptor, target object

The call of this.getHandler(processedRequest) in this method initializes the parameter mappedHandler of HandlerExecutionChain

image-20230613171135917

Let's take a look at what the getHandler method is, as shown below

If the parameter handlerMappings is not empty, loop it

image-20230613171243796

What is the handlerMappings parameter? Click to see

Discovery is the final collection of HandlerMapping

The filling of HandlerMapping is explained in the previous 1.3

image-20230613171338114

Go back to the getHandler method, where the mapping.getHandler(request) method is called when traversing the collection

image-20230613171718008

Let's take a look at what the mapping.getHandler method does

image-20230613171802289

Find the corresponding implementation, choose the first one

image-20230613171831955

Then the corresponding implementation in this class calls the getHandlerExecutionChain method

image-20230613172046527

Look at the getHandlerExecutionChain method again

image-20230613172423819

Finally, the chain parameter is returned to the doDispatcher method, as marked in red below

image-20230613173020004

The above process is the place marked in red in the figure below

image-20230613173105376

2.3 HandlerAdapter executes the target method

The doDispatcher method has not been completed, continue to look down

Going down will call the getHandlerAdapter method

image-20230613174053137

Continuing to go down, the preHandle pre-method of the interceptor will be executed

image-20230613174353969

execute target method

image-20230613174432492

execute post method

image-20230613174446037

Then we found that the HandlerAdapter object was not executed when the pre-method and post-method were executed

But when the target method is executed, it is executed by the HandlerAdapter object

Then we can look at the handle method and execute the target method

Found that it is not implemented, let's look at the implementation of the subclass

image-20230613175007402

Select the first one in the image below

image-20230613175047564

Go down the screenshot

image-20230613175117213

image-20230613175141977

Finally arrived at the following place

image-20230613175204955

Continue to execute, and you will enter the method marked in red below

image-20230613175458582

continue to click in

image-20230613175547655

image-20230613175625668

At the following place, look at the parameters

image-20230613175727043

The parameters in the above figure are the corresponding parameters when we visit

image-20230613175754331

Then click into the doInvoke method

image-20230613175842058

Then I found the method of executing method.invoke(this.getBean(), args)

Reflect code, and finally execute the target method through reflection

image-20230613180008739

Guess you like

Origin blog.csdn.net/weixin_51351637/article/details/131195207