Difference between traditional tomcat startup service and springboot startup built in tomcat service of recommendation

  • 2021-10-27 09:48:12
  • OfStack

spring Integrates springmvc

spring integrates the configuration of web. xml in springmvc as follows, tomcat will load the contents of web. xml during startup, ContextLoaderListener implements ServletContextListener interface in tomcat, so initialize spring container through ContextLoaderListener during startup of tomcat container, and load spring configuration file specified by classpath: spring/applicationContext-*. xml, which I only configured < context: component-scan base-package= "org. com. yp"/ > For bean registration by scanning the classes under the org. com. yp package, including annotations such as @ Component @ Controller @ Service. The bean registration is loaded with the bean definition through the methods of the AbstractXmlApplicationContext. loadBeanDefinitions class.

Loading the bean definition in spring loads bean with the ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory () method in the org. springframework. context. context # refresh method, which then calls the org. springframework. context. support. AbstractRefreshableApplicationContext # refreshBeanFactory method to create the bean factory and loads the bean definition.


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                             http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>Archetype Created Web Application</display-name>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <!--  Loading spring Container  -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring/applicationContext-*.xml</param-value>
  </context-param>
​
  <servlet>
    <servlet-name>mvc-dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--  Configure springMVC Configuration file to be loaded -->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring/spring-*.xml</param-value>
    </init-param>
  </servlet>
​
  <servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <!--  Match all requests by default  -->
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

When the tomcat container is started and the resource is accessed through the path, the org. springframework. web. servlet. HttpServletBean # init method will be called for the first time, and the method class will not be used in subsequent http requests; HttpServletBean implements the specification of Servlet interface, so when init method is initialized through servlet interface, the loading class defined in springmvc configuration will be loaded from spring container. spring and springmvc are parent-child container relations. The following is init method of HttpServletBean


public final void init() throws ServletException {
		// Set bean properties from init parameters.
		PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
		if (!pvs.isEmpty()) {
			try {
				BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
				ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
				bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));
				initBeanWrapper(bw);
				bw.setPropertyValues(pvs, true);
			}
			catch (BeansException ex) {
				if (logger.isErrorEnabled()) {
					logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
				}
				throw ex;
			}
		}

        //  Finally, the call is made org.springframework.context.ConfigurableApplicationContext#refresh Container refresh method, 
        //  Go on springmvc Container initialization 
		initServletBean();
	}
    }

springboot Startup Container

springboot is started by initializing the context environment of spring (including bean factory) in org. springframework. boot. SpringApplication # run (java. lang. String...) method of springboot, and then calling ConfigurableApplicationContext # refresh method in Spring container through org. springframework. boot # refreshContext method to initialize bean. In an environment where spring is integrated with springmvc, the loading defined by bean is in the org. springframework. context. support # obtainFreshBeanFactory method, and in springboot is in the

org. springframework. context. support. AbstractApplicationContext # invokeBeanFactoryPostProcessors method, in which bean definition is loaded through ConfigurationClassPostProcessor class, which implements BeanDefinitionRegistryPostProcessor interface, which allows processing of bean definition.


// spring In BeanDefinitionRegistryPostProcessor Yes BeanFactoryPostProcessor Subinterfaces of, 
// BeanFactoryPostProcessor The role of is in bean Execute the method when the definition information of has been loaded but has not been initialized postProcessBeanFactory( ) Method, 
//  And BeanDefinitionRegistryPostProcessor Is in BeanFactoryPostProcessor Execute in front of the source code 
// org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors() The execution order is defined in the method 
// BeanFactoryPostProcessor Yes bean Factory bean Attribute handles containers, which is popular 1 Some are the ones that can manage us bean All in the factory beandefinition (Uninstantiated) data, and properties can be modified at will. 
public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            prepareRefresh();
            
            // Gets tells the subclass to initialize Bean Factory   Will bean Load into the cache  spring springmvc Integration is initialized here bean Adj. 
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
            
            prepareBeanFactory(beanFactory);
​
            try {
                postProcessBeanFactory(beanFactory);
​
                // springboot The container starts loading at this time, and the following are initialized bean name
                //0 = "org.springframework.context.annotation.internalConfigurationAnnotationProcessor" = "Correspondence ConfigurationClassPostProcessor Class 
                //1 = "org.springframework.context.annotation.internalAutowiredAnnotationProcessor" = "  AutowiredAnnotationBeanPostProcessor
                //2 = "org.springframework.context.annotation.internalCommonAnnotationProcessor" = "  CommonAnnotationBeanPostProcessor
                //3 = "org.springframework.context.event.internalEventListenerProcessor" = "  EventListenerMethodProcessor
                //4 = "org.springframework.context.event.internalEventListenerFactory" = "  DefaultEventListenerFactory
                //  Call our bean Post processor of factory . Loading bean Definition (not instantiation) , Pass ConfigurationClassPostProcessor To load the scan path in the startup class 
                //  Then go down the path to bean Load in 
                invokeBeanFactoryPostProcessors(beanFactory);
​
                registerBeanPostProcessors(beanFactory);
​
                initMessageSource();
​
                initApplicationEventMulticaster();
​
                //  This method is also implemented by leaving subclasses springboot It is also started from this method tomat Adj. .
                onRefresh();
​
                registerListeners();
​
                // Instantiate our remaining single instances bean.
                finishBeanFactoryInitialization(beanFactory);
​
                //  Last container refresh   Publish refresh event (Spring cloud It also started from here )
                finishRefresh();
            }
​
            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception  encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }
​
                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();
​
                // Reset 'active' flag.
                cancelRefresh(ex);
​
                // Propagate exception to caller.
                throw ex;
            }
​
            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
            }
        }
    }

Related articles: