SpringMVC DispatcherServlet初始化过程

先来上一张类的结构图:

图里只画了跟初始化相关的方法。

首先DispatcherServlet也是一个Servlet,初始化从init()方法开始。

下面就具体看看ini()是怎么实现的吧。

1.Servlet 是个接口;

public void init(ServletConfig config) throws ServletException;2.GenericServlet 中实现了初始化方法。 public void init(ServletConfig config) throws ServletException {this.config = config;this.init();}这里调用了一个没有参数的init();是个空方法;public void init() throws ServletException {}3.HttpServlet 没有对初始化相关的方法进行覆盖。

4.HttpServletBean,重写了init()方法。

@Overridepublic 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");}}其中又掉了一个initServletBean();方法,这本类中也是个空实现。protected void initServletBean() throws ServletException {}5.FrameworkServlet 果不其然的重写了上边留空的方法:initServletBean();@Overrideprotected 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");}}在这个方法中最重要的就是调用了一个initWebApplicationContext() 方法。protected WebApplicationContext initWebApplicationContext() {WebApplicationContext rootContext =WebApplicationContextUtils.getWebApplicationContext(getServletContext());WebApplicationContext wac = null;if (this.webApplicationContext != null) {// A context instance was injected at construction time -> use itwac = 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, etcif (cwac.getParent() == null) {// The context instance was injected without an explicit parent -> set// the root application context (if any; may be null) as the parentcwac.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 idwac = findWebApplicationContext();}if (wac == null) {// No context instance is defined for this servlet -> create a local onewac = 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;}一系列的赋值和判断,最关键的,跟初始化相关的,,就是调用了onRefresh(),同样的套路,这个方法在本类中为空实现,留给子类去实现。放下一处烦恼,收获一个惊喜;放下一种偏见,收获一种幸福;

SpringMVC DispatcherServlet初始化过程

相关文章:

你感兴趣的文章:

标签云: