FrameworkServlet is the base class for spring MVC’s next setVlet, It inherits the HttpServletBean HttpServletBean, and inherits the HttpServlet through HttpServletBean source code parsing we came to know that HttpServletBean rewrite the servlet init () method, InitServletBean () is called in the init() method, and initServletBean() is an empty method that requires subclasses to implement
What does FrameworkServlet do?
-
Implement initServletBean() in HttpServletBean and create or refresh the WebApplicationCentext container in initServletBean()
protected final void initServletBean() throws ServletException { this.getServletContext().log("Initializing Spring " + this.getClass().getSimpleName() + " '" + this.getServletName() + "'"); if (this.logger.isInfoEnabled()) { this.logger.info("Initializing Servlet '" + this.getServletName() + "'"); } long startTime = System.currentTimeMillis(); Try {/ / initialization or refresh WebApplicationContext container enclosing WebApplicationContext = this. InitWebApplicationContext (); this.initFrameworkServlet(); } catch (RuntimeException | ServletException var4) { this.logger.error("Context initialization failed", var4); throw var4; } if (this.logger.isDebugEnabled()) { String value = this.enableLoggingRequestDetails ? "shown which may lead to unsafe logging of potentially sensitive data" : "masked to prevent unsafe logging of potentially sensitive data"; this.logger.debug("enableLoggingRequestDetails='" + this.enableLoggingRequestDetails + "': request parameters and headers will be " + value); } if (this.logger.isInfoEnabled()) { this.logger.info("Completed initialization in " + (System.currentTimeMillis() - startTime) + " ms"); }}Copy the code
protected WebApplicationContext initWebApplicationContext() { WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext()); WebApplicationContext wac = null; if (this.webApplicationContext ! = null) {/ / instance in the constructor injected wac = this. WebApplicationContext; if (wac instanceof ConfigurableWebApplicationContext) { ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext)wac; // The current container is unavailable if (! Cwac. isActive()) {if (cwac.getParent() == null) {cwac.setParent(rootContext); } / / this method can be configured in the refresh WebApplicationContext, enclosing configureAndRefreshWebApplicationContext (cwac); }}} the if (wac = = null) {/ / lookup from ContextAttribute WebApplicationContext wac = this. FindWebApplicationContext (); } the if (wac = = null) {/ / if there is still no find would be to create a WebApplicationContext wac = this. CreateWebApplicationContext (rootContext); } if (! Enclosing refreshEventReceived) {/ / refresh WebApplicationContext configuration, onRefresh need to subclass to be realized Synchronized (enclosing onRefreshMononRefresh need to subclass to achieve itor) {enclosing onRefresh (wac); }} the if (this. PublishContext) {/ / to save the current container to ServletContext String attrName = this. GetServletContextAttributeName (); this.getServletContext().setAttribute(attrName, wac); } return wac; }Copy the code
Finding and creating a WebApplicationContext involves the following steps
- Enclosing webApplicationContext is not equal to null, then judge whether webApplicationContext containers currently available, unavailable, determine whether to set the parent container, Last call this. ConfigureAndRefreshWebApplicationContext (cwac) refresh webApplicationContext configuration
- If webApplicationContext is empty, the corresponding webApplicationContext can be queried from the servlet parameter in the web. XML configuration
- If not, create webApplicationContext
configureAndRefreshWebApplicationContext
Whether it’s simply create or through the constructor injection, finally will be called to configureAndRefreshWebApplicationContext () method, ConfigureAndRefreshWebApplicationContext () calls the AbstractApplicationContext. Refresh () to refresh the context,
AbstractApplicationContext. Refresh () in the last step calls finishRefresh issued ContextRefreshedEvent events (), call the event, Thus FrameworkServlet listens for ContextRefreshedEvent events and calls the onRefresh() method.
OnRefresh () is finally implemented by the DispatcherServlet, which initializes its nine components
conclusion
- HttpServletBean overrides the Init () method of GenericServlet, which calls the initServletBean() method, which is overridden by the FrameworkServlet
- In FrameworkServlet initServletBean () method, it calls the initWebApplicationContext () method
- In this method, it checks whether webApplicationContext ConfigurableWebApplicationContext instance
- If so, then call configureAndRefreshWebApplicationContext () method
- Because it calls refresh on the webApplicationContext
- View AbstractApplicationContext refresh () method of implementation, the last call finishRefresh () method
- In this method it publishes ContextRefreshedEvent
- In FrameworkServlet there is a private class, ContextRefreshListener, that implements ApplicationListener
- The onApplicationEvent() method on this class calls the onApplicationEvent() method on the FrameworkServlet
- In this method, it invokes the onRefresh method overridden by the DispatcherServlet