The startup process of spring - the principle of spring and springMVC parent-child container

To understand the relationship between these three contexts, you need to be familiar with how spring is started in the web container. The startup process of spring is actually the startup process of its IoC container. For web programs, the startup process of the IoC container is the process of establishing the context.

The startup process of spring:

  1. First of all, for a web application, it is deployed in the web container, and the web container provides a global context, which is the ServletContext, which provides the host environment for the subsequent spring IoC container;

  2. Secondly, contextLoaderListener will be provided in web.xml. When the web container starts, the container initialization event will be triggered. At this time, the contextLoaderListener will listen to this event, and its contextInitialized method will be called. In this method, spring will initialize a startup context, which is called the root context, namely WebApplicationContext , which is an interface class, to be precise, its actual implementation class is XmlWebApplicationContext. This is spring's IoC container, and the configuration of its corresponding bean definition is specified by the context-param tag in web.xml. After the IoC container is initialized, spring uses WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE as the attribute Key and stores it in the ServletContext for easy access;

  3. Once again, after the contextLoaderListener listener is initialized, it starts to initialize the Servlet configured in web.xml. This servlet can be configured with multiple ones. Take the most common DispatcherServlet as an example, this servlet is actually a standard front-end controller for forwarding, Match and process each servlet request. The DispatcherServlet context will establish its own IoC context during initialization to hold spring mvc-related beans. When establishing DispatcherServlet's own IoC context, it will use WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE to obtain the previous root context (ie WebApplicationContext) from ServletContext as the parent context of its own context. After you have this parent context, initialize the context you hold. The work of this DispatcherServlet to initialize its own context can be seen in its initStrategies method. The general work is to initialize processor mapping, view resolution, and so on. The default implementation class of the context held by this servlet is also mlWebApplicationContext. After initialization, spring uses the attribute related to the name of the servlet (here, it is not simply named as the servlet key, but through some conversion, you can view the source code by yourself) as the attribute key, and also save it in the ServletContext, so that subsequent use. In this way, each servlet holds its own context, that is, it has its own independent bean space, and each servlet shares the same beans, that is, those beans defined by the root context (the context initialized in step 2).

After talking about the initialization process of the spring context, the relationship between these three contexts should be understood. If it's still not clear, I can't help but look at the code by myself.

===============================================================================================================

 

The concept of parent-child context has been involved in a project recently.

What is a parent-child context?

Parent context:

Use the listener listener to load the configuration file, as follows:

?

1

2

3

<listener>   

  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>   

</listener>

 

Spring will create a WebApplicationContext context, called the parent context (parent container), which is stored in the ServletContext, and the key is the value of WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE.

You can use the tool class provided by Spring to take out the context object: WebApplicationContextUtils.getWebApplicationContext(ServletContext);

Subcontext:

When using Spring MVC to handle interception-related requests, DispatchServlet is configured:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<servlet>

    <servlet-name>dispatcherServlet</servlet-name>

    <servlet-class>org.springframework.web.servlet.DispatcherServlet

    </servlet-class>

    <init-param>

        <param-name>contextConfigLocation</param-name>

        <param-value>/WEB-INF/applicationContext-mvc.xml</param-value>

    </init-param>

    <load-on-startup>1</load-on-startup>

</servlet>

 

<servlet-mapping>

    <servlet-name>dispatcherServlet</servlet-name>

    <url-pattern>/</url-pattern>

</servlet-mapping>

 

Each DispatchServlet will have its own context, called a subcontext, which is also stored in the ServletContext, and the key is "org.springframework.web.servlet.FrameworkServlet.CONTEXT" + Servlet name. When a Request object is generated, the sub-context object (WebApplicationContext) is stored in the Request object, and the key is DispatcherServlet.class.getName() + ".CONTEXT".

You can use the tool class to take out the context object: RequestContextUtils.getWebApplicationContext(request);

 

Access permissions for parent context (parent container) and child context (child container):

The child context can access the beans in the parent context, but the parent context cannot access the beans in the child context.

 

Whether the parent context is used or not

Option 1, traditional type:

Beans that save data sources, service layers, DAO layers, and transactions in the parent context container.

The Bean that holds Mvc-related Actions in the subcontext container.

Transaction control is at the service layer.

Since the parent context container cannot access the content in the child context container, the transaction bean is in the parent context container and cannot access the content in the child context container, so AOP (transaction) cannot be performed on the Action in the child context container.

Of course, as a "traditional" solution, this is not necessary.

 

Option 2, Radical:

The idea of ​​"interface-oriented programming" in the Java world is correct, but in the system where addition, deletion, modification and checking are the main business, Dao layer interface, Dao layer implementation class, Service layer interface, Service layer implementation class, Action parent class, Action. Plus numerous O(vo\po\bo) and jsp pages. Write a small function 7 or 8 classes and write it out. The developer said that I just wanted to do personal work and compete with PHP and ASP for a job, but I was a Java programmer. The best result is that big projects can be done well and small projects can be done quickly. So the "radical" solution appeared ----- no interface, no Service layer, and no many O(vo\po\bo). In which layer is there no Service layer transaction control? Had to go up the Action layer.

This article does not want to say whether this is the right idea, what I want to say is that Spring does not restrict you from doing this.

You won't be able to achieve this because of the parent-child context. The solution is to just use the child context container, not the parent context container. Therefore, the data source, service layer, DAO layer, transaction bean, and action bean are all placed in the subcontext container. It can be achieved, and the transaction (annotation transaction) will work normally. That's aggressive enough.

Summary: Do not use the listener listener to load the spring configuration file, only use the DispatcherServlet to load the spring configuration, do not use the parent-child context, only use one DispatcherServlet, things are simple, and there is no trouble.

 

 

 

Java--big projects can be done well--do it in the traditional way, do it in a proper way, easy to expand, easy to maintain.

Java - small projects can be done quickly - do it in a radical way, and a version can be produced in a week. First, go online to receive feedback from the market (users), then improve, and then give feedback. Time is life (cost).

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326647295&siteId=291194637