summary
Do you know how Tomcat loads Spring and Spring MVC? Today we'll figure out the process (record the most critical things)
It will involve large and small knowledge, including design patterns during loading, Servlet knowledge, etc. you must gain something after reading it~
Tomcat
tomcat is a Web application server written in Java, also known as Web container, which specially runs Web programs
tomcat startup
After tomcat is started, a Jvm (Java virtual machine) process will be generated in the operating system to listen for the HTTP/1.1 protocol messages sent from the configured listening port (8080 by default)
The default configuration file looks like this
When Tomcat is started, it will load the project in webapps under its installation directory (the war package will be automatically decompressed into a project)
Small question: are multiple projects in webapps running on the same JVM
It runs on the same JVM (the one created when Tomcat starts). Multiple projects are multiple threads. The reason why data is not shared between projects is that class loaders are different
Load Web application (Spring + spring MVC framework)
After Tomcat is started, the most important thing is to generate the ServletContext (Tomcat context), and then load the project according to the web.xml in the webapps project
The following is a partial web of a spring MVC + spring project xml
Initialize Spring
tomcat will first load into the ContextLoaderListener, and then apply the ApplicationContext The parameters written in XML are injected to complete a series of Spring initialization (such as various bean s, database resources, etc.)
Here is the initialization of the Ioc container we often hear. We search this class and find the following code
The most important thing here is to initialize the Spring context WebApplicationContext through the ServletContext and store it in the ServletContext
WebApplicationContext many old fellow iron masters know that we often use webApplicationContext.. GetBean () to get the classes managed by Spring, so this is also the core of the IOC container
Spring uses this listener to start its own method. It is also a design pattern called observer pattern:
The whole process is like this. When Tomcat loads the webapps project, it first loads it on the web through reflection XML (all in an array)
At some point, my tomcat (event source, event origin) will launch an event called ServletContextEvent (with various parameters)
For any class that implements the ServletContextListener interface, I will call the contextInitialized method inside and pass this event parameter in
Cough, now I look at whether there are qualified (traversal) in this array. If I find that there is a class (instanceof interface) that implements this interface, I call the contextInitialized method
So Spring is loaded dynamically~~
Digression:
To load a class, you can use the complete class name and load it through java reflection, class Forname (class name)
You can also load a new class directly
Initialize spring MVC
Look at the configuration file. The tag is servlet. We have to first understand what servlet is
Introduction to Servlet
Servlet is an interface for web communication
Tomcat has a set of defined programs (in fact, not only tomcat, but also web application servers written in java, such as Jetty, etc.)
1. When tomcat loads a class, if it implements the Servlet interface, it will be recorded in a Map, and then execute the init() method to initialize the Servlet
2. When tomcat receives the browser's request, it will find the Servlet of the corresponding path in the Map for processing. The path is the parameter written in the < URL pattern > tag, and call the service() method
3. When the Servlet is about to be destroyed, the destroy() method is called once
When you see this, do you feel familiar? It's similar to Spring loading. It's all arranged by fate (tomcat) after implementing an interface~~
Of course, it's too troublesome for us to implement the Servlet interface ourselves, so HttpServlet (an abstract class) helps us implement most methods (including http header setting, doXXX method judgment, etc.)
So we just need to inherit HttpServlet and implement several methods
Spring MVC loading
Why should we talk about Servlet? Because the core of spring MVC is dispatcher Servlet (front controller), as shown in the figure
Dispatcher servlet is implemented by spring MVC. It has been implemented very well. We don't need to touch it again
tomcat from web The DispatcherServlet is loaded in XML, and then its init() method is called
The Servlet configuration file defaults to / WEB-INF / < Servlet name > - Servlet XML, so it is now called project Servlet by default xml
Of course, you can also specify your own files
When spring MVC is loaded, the browser has a request, if yes At the end of html, tomcat will be handed over to dispatcher servlet for processing
The dispatcher servlet will find the corresponding processor processing according to the path, which can be understood as the Controller we wrote received it (a blog will be written for the specific spring MVC processing flow)
At this point, the browser sends a request to execute the code we wrote, and the process is over ~ ~ sprinkle flowers~~
Container problems in Spring and Spring MVC
Now that we talk about tomcat loading these two frameworks, we find that they are not available on the web In XML, Spring loading is written before dispatcher servlet loading
Let's take a look at the initialization method of DispatcherServlet. Since DispatcherServlet is inherited layer by layer, the initialization method also becomes
We can see that HttpServlet implements init() and leaves the initServletBean() abstract method
FrameworkServlet implements the initServletBean() method and defines it as final (not allowed to rewrite). In this method, initWebApplicationContext() is called.
initWebApplicationContext() states that if there is a webapplication in tomcat, get it and set it as the parent context of spring MVC
So far, the dispatcher servlet initialization is completed (of course, I have omitted other initialization tasks)
Therefore, there is a parent-child relationship between Spring and Spring MVC containers. Since child containers can access the contents of the parent container, but not vice versa, do not want to automatically inject Controller into the Service
Therefore, there will be the following situations
What happens if the Controller is also swept in when the Spring configuration scans the package
Then, the Controller will enter the context of Spring, and there will be no Controller in Spring MVC. When there is a request to the dispatcher servlet, the Controller will not be found and 404
Little question: can spring MVC scan all packages
This is OK. Spring MVC can be used without spring, but spring is added to be more compatible with other frameworks (database framework, etc.)
However, if you use spring, you can't do this. Spring sweeps the Controller and spring MVC sweeps the Controller once. All kinds of strange problems will occur
Comment
</div></div><div id="xcp-publish-main-right_1640676274113" class="right"> <div class="x-interact-publish"> <div class="x-interact-publish-cont"> <textarea contenteditable="true" class="text-area placeholder" placeholder="Publish divine comments"></textarea> <div class="other"></div> </div> <div class="x-interact-publish-panel-center"> </div> <div class="x-interact-publish-opt no-radio"> <span class="emoj"></span> <span class="radio "></span> <span class="extra"></span> <span class="send disabled">publish</span> </div> <div class="x-interact-publish-panel-bottom"> <div id="xcp-publish-main-right_1640676274113_emoj_panel" class="emoj-panel "> </div> </div> </div> </div></div></div></div><div><div class="xcp-list"><h2 class="xcp-list-title">Comment list (5)</h2><div class="xcp-list-list"><div><div class="xcp-item" data-reply-id="1115088479283434018"><div class="left"><div class="x-avatar"> <div class="x-avatar-placeholder"></div> <div class="x-avatar-img" style="background-image: url(https://pic.rmb.bdstatic.com/9b538330360cce42158787b21619d1ac.jpeg?x-bce-process=image/resize,m_lfit,w_200,h_200&autime=57924)"></div> <div class="x-avatar-vip vip-3 "></div> </div></div><div class="right"> <div class="user-bar"> <h5 class="user-bar-uname">computer java programming<span class="user-bar-lz">author</span></h5> <span class="user-bar-verified">High quality technology creators</span> </div> <div class="x-interact-rich-text rich-text" data-reply-id="1115088479283434018"> <span class="type-text">Long press the end of the article to send praise to the third company, and support the author of this article to write more~</span> </div> <div class="interact-bar" data-reply-id="1115088479283434018"> <div class="interact-bar-left"> <span class="time">2020-12-11</span> <span class="report">report</span> </div> <div class="interact-bar-right"> <div class="reply"> <i class="icon reply-icon"></i> <span class="reply-text">reply</span> </div> <div class="like "> <i class="icon like-icon"></i> <span class="like-text">5</span> </div> </div> </div> </div></div></div><div><div class="xcp-item" data-reply-id="1115089418731009516"><div class="left"><div class="x-avatar"> <div class="x-avatar-placeholder"></div> <div class="x-avatar-img" style="background-image: url(https://himg.bdimg.com/sys/portrait/item/wise.1.b5d7bfeb.vBol4CO_C9pHHNKBHtUEQg.jpg?time=5485)"></div> </div></div><div class="right"> <div class="user-bar"> <h5 class="user-bar-uname">Wu Hongliang 8 q</h5> </div> <div class="x-interact-rich-text rich-text" data-reply-id="1115089418731009516"> <span class="type-text">Well written</span> </div> <div class="interact-bar" data-reply-id="1115089418731009516"> <div class="interact-bar-left"> <span class="time">2020-12-11</span> <span class="report">report</span> </div> <div class="interact-bar-right"> <div class="reply"> <i class="icon reply-icon"></i> <span class="reply-text">reply</span> </div> <div class="like "> <i class="icon like-icon"></i> <span class="like-text">fabulous</span> </div> </div> </div> <div><div class="xcp-list"><div class="xcp-list-list is-second"><div><div class="xcp-item" data-reply-id="1115089546368175712"><div class="left"><div class="x-avatar is-small"> <div class="x-avatar-placeholder"></div> <div class="x-avatar-img" style="background-image: url(https://pic.rmb.bdstatic.com/9b538330360cce42158787b21619d1ac.jpeg?x-bce-process=image/resize,m_lfit,w_200,h_200&autime=57924)"></div> <div class="x-avatar-vip vip-3 is-small-vip"></div> </div></div><div class="right"> <div class="user-bar"> <h5 class="user-bar-uname">computer java programming<span class="user-bar-lz">author</span></h5> <span class="user-bar-verified">High quality technology creators</span> </div> <div class="x-interact-rich-text rich-text" data-reply-id="1115089546368175712"> <span class="type-text">thank you</span> </div> <div class="interact-bar" data-reply-id="1115089546368175712"> <div class="interact-bar-left"> <span class="time">2020-12-11</span> <span class="report">report</span> </div> <div class="interact-bar-right"> <div class="reply"> <i class="icon reply-icon"></i> <span class="reply-text">reply</span> </div> <div class="like "> <i class="icon like-icon"></i> <span class="like-text">fabulous</span> </div> </div> </div> </div></div></div></div></div></div></div></div></div><div><div class="xcp-item" data-reply-id="1115088554084117514"><div class="left"><div class="x-avatar"> <div class="x-avatar-placeholder"></div> <div class="x-avatar-img" style="background-image: url(https://himg.bdimg.com/sys/portrait/item/wise.1.10374774.LXOy63Z9ydhLn9eb6f8vOg.jpg?time=1954)"></div> </div></div><div class="right"> <div class="user-bar"> <h5 class="user-bar-uname">hanbd08</h5> </div> <div class="x-interact-rich-text rich-text" data-reply-id="1115088554084117514"> <span class="type-text">Forwarded</span> </div> <div class="interact-bar" data-reply-id="1115088554084117514"> <div class="interact-bar-left"> <span class="time">2020-12-11</span> <span class="report">report</span> </div> <div class="interact-bar-right"> <div class="reply"> <i class="icon reply-icon"></i> <span class="reply-text">reply</span> </div> <div class="like "> <i class="icon like-icon"></i> <span class="like-text">fabulous</span> </div> </div> </div> <div><div class="xcp-list"><div class="xcp-list-list is-second"><div><div class="xcp-item" data-reply-id="1115103021434404218"><div class="left"><div class="x-avatar is-small"> <div class="x-avatar-placeholder"></div> <div class="x-avatar-img" style="background-image: url(https://pic.rmb.bdstatic.com/9b538330360cce42158787b21619d1ac.jpeg?x-bce-process=image/resize,m_lfit,w_200,h_200&autime=57924)"></div> <div class="x-avatar-vip vip-3 is-small-vip"></div> </div></div><div class="right"> <div class="user-bar"> <h5 class="user-bar-uname">computer java programming<span class="user-bar-lz">author</span></h5> <span class="user-bar-verified">High quality technology creators</span> </div> <div class="x-interact-rich-text rich-text" data-reply-id="1115103021434404218"> <span class="type-text">thank</span> </div> <div class="interact-bar" data-reply-id="1115103021434404218"> <div class="interact-bar-left"> <span class="time">2020-12-13</span> <span class="report">report</span> </div> <div class="interact-bar-right"> <div class="reply"> <i class="icon reply-icon"></i> <span class="reply-text">reply</span> </div> <div class="like "> <i class="icon like-icon"></i> <span class="like-text">fabulous</span> </div> </div> </div> </div></div></div></div></div></div></div></div></div></div> <div class="xcp-list-loader no-more" data-parent-id="0"> <span>No more</span> </div> </div></div></div><!--504--></div>