Dispatcher Servlet Initialization for Spring MVC Source Learning

Servlet life cycle (review)

1. The servlet container initializes the corresponding servlet call init() method after receiving the first http request

Initialized servlets are singletons, and how many servlet instances will there be in web.xml when you configure how many servlets

Configuring < load-on-startup > 1 </load-on-startup > when configuring servlets in web.xml initializes the servlet instance at container startup. The default value is 0.

2. service() method

servlet handles client requests by calling service()

3.destory() method

The servlet terminates by calling the destory() method.

Eventually, the method is marked as recoverable and recycled by the virtual machine garbage collector.

Initialization of Dispatcher Servlet

This class is the front-end controller of spring MVC framework, which distributes and processes client requests. The diagram of the relationship between this class and other classes is shown below. The HttpServletBean inherits the HttpServlet and overrides the init() method.

1.HttpServletBean

As you can see from the figure above, the initialization of the Dispatcher Servlet starts with the init() mode of the HttpServletBean. Because < load-on-startup > 1 </load-on-startup > is configured in the web.xml file when using Springmvc, the Servlet container initializes the Dispatcher Servlet at startup, and according to the class initialization process of java, the constructor of the parent class is invoked to initialize the parent class first. And so on. The following is the implementation of init() of HttpServletBean:

public final void init() throws ServletException {
   if (logger.isDebugEnabled()) {
      logger.debug("Initializing servlet '" + getServletName() + "'");
   }

   // Set bean properties from init parameters.
   try {
      PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
      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) {
      logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
      throw ex;
   }

   // Let subclasses do whatever initialization they like.
   initServletBean();

   if (logger.isDebugEnabled()) {
      logger.debug("Servlet '" + getServletName() + "' configured successfully");
   }
}

As you can see from this method, the initServletBean() method is called. The annotation indicates that this method lets the subclass do whatever initialization it wants to do. The initServletBean() method is an empty implementation implemented by subclasses

/**
 * Subclasses may override this to perform custom initialization.
 * All bean properties of this servlet will have been set before this
 * method is invoked.
 * <p>This default implementation is empty.
 * @throws ServletException if subclass initialization fails
 */
protected void initServletBean() throws ServletException {
}

Method annotation: Subclasses may override this method to implement defined-only initialization, and all property settings for this servlet have been completed before the method is executed.

2.FrameworkServlet

Framework Servlet overrides the initServletBean method:

/**
 * Overridden method of {@link HttpServletBean}, invoked after any bean properties
 * have been set. Creates this servlet's WebApplicationContext.
 */
@Override
protected final void initServletBean() throws ServletException {
   getServletContext().log("Initializing Spring FrameworkServlet '" + getServletName() + "'");
   if (this.logger.isInfoEnabled()) {
      this.logger.info("FrameworkServlet '" + getServletName() + "': initialization started");
   }
   long startTime = System.currentTimeMillis();

   try {
      this.webApplicationContext = initWebApplicationContext();
      initFrameworkServlet();
   }
   catch (ServletException ex) {
      this.logger.error("Context initialization failed", ex);
      throw ex;
   }
   catch (RuntimeException ex) {
      this.logger.error("Context initialization failed", ex);
      throw ex;
   }

   if (this.logger.isInfoEnabled()) {
      long elapsedTime = System.currentTimeMillis() - startTime;
      this.logger.info("FrameworkServlet '" + getServletName() + "': initialization completed in " +
            elapsedTime + " ms");
   }
}

This method mainly calls the initWeb Application Context () method to see the implementation of initWeb Application Context ().

/**
 * Initialize and publish the WebApplicationContext for this servlet.
 * <p>Delegates to {@link #createWebApplicationContext} for actual creation
 * of the context. Can be overridden in subclasses.
 * @return the WebApplicationContext instance
 * @see #FrameworkServlet(WebApplicationContext)
 * @see #setContextClass
 * @see #setContextConfigLocation
 */
protected WebApplicationContext initWebApplicationContext() {
   WebApplicationContext rootContext =
         WebApplicationContextUtils.getWebApplicationContext(getServletContext());
   WebApplicationContext wac = null;

   if (this.webApplicationContext != null) {
      // A context instance was injected at construction time -> use it
      wac = this.webApplicationContext;
      if (wac instanceof ConfigurableWebApplicationContext) {
         ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;
         if (!cwac.isActive()) {
            // The context has not yet been refreshed -> provide services such as
            // setting the parent context, setting the application context id, etc
            if (cwac.getParent() == null) {
               // The context instance was injected without an explicit parent -> set
               // the root application context (if any; may be null) as the parent
               cwac.setParent(rootContext);
            }
            configureAndRefreshWebApplicationContext(cwac);
         }
      }
   }
   if (wac == null) {
      // No context instance was injected at construction time -> see if one
      // has been registered in the servlet context. If one exists, it is assumed
      // that the parent context (if any) has already been set and that the
      // user has performed any initialization such as setting the context id
      wac = findWebApplicationContext();
   }
   if (wac == null) {
      // No context instance is defined for this servlet -> create a local one
      wac = createWebApplicationContext(rootContext);
   }

   if (!this.refreshEventReceived) {
      // Either the context is not a ConfigurableApplicationContext with refresh
      // support or the context injected at construction time had already been
      // refreshed -> trigger initial onRefresh manually here.
      onRefresh(wac);
   }

   if (this.publishContext) {
      // Publish the context as a servlet context attribute.
      String attrName = getServletContextAttributeName();
      getServletContext().setAttribute(attrName, wac);
      if (this.logger.isDebugEnabled()) {
         this.logger.debug("Published WebApplicationContext of servlet '" + getServletName() +
               "' as ServletContext attribute with name [" + attrName + "]");
      }
   }

   return wac;
}

The main function of this method is to initialize and publish the application context of the servlet, and then call the onRefresh(wac) method to force the refresh context. The onRefresh (Application Context context) method is an empty implementation implemented by the Dispatcher Servlet. As follows:

/**
 * This implementation calls {@link #initStrategies}.
 */
@Override
protected void onRefresh(ApplicationContext context) {
   initStrategies(context);
}

This method calls initStrategies (Application Context context) as follows:

/**
 * Initialize the strategy objects that this servlet uses.
 * <p>May be overridden in subclasses in order to initialize further strategy objects.
 */
protected void initStrategies(ApplicationContext context) {
   initMultipartResolver(context);
   initLocaleResolver(context);
   initThemeResolver(context);
   initHandlerMappings(context);
   initHandlerAdapters(context);
   initHandlerExceptionResolvers(context);
   initRequestToViewNameTranslator(context);
   initViewResolvers(context);
   initFlashMapManager(context);
}

Finally initStrategies () is called to initialize the policy objects needed by the Dispatcher Servlet object.

 

 

 

 

 

 

 

Tags: xml Spring Attribute Java

Posted on Fri, 09 Aug 2019 01:53:57 -0700 by BLeez