springMVC读书笔记--spring启动时web初始化

来源:互联网 发布:网络延时1000 编辑:程序博客网 时间:2024/06/05 19:43

web启动初始化的时候,重要的两个点:

<context-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/spring/base-context.xml/WEB-INF/spring/security-context-ajax.xml/WEB-INF/spring/security-context.xml</param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><servlet><servlet-name>Spring MVC Dispatcher Servlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/spring/servlet-context.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>Spring MVC Dispatcher Servlet</servlet-name><url-pattern>/</url-pattern></servlet-mapping>
其中重要的两个类为DispatcherServlet和ContextLoaderListener其中:

1、ContextLoaderListener 初始化,调用initWebApplicationContext方法,初始化设置webApplication的上下文,并将上下文放置servletContext.setAttribute中,初始化的上下文加载的Bean是对于整个应用程序共享的,不管是使用什么表现层技术,一般如DAO层、Service层Bean;
2、DispatcherServlet初始化的上下文加载的Bean是只对Spring Web MVC有效的Bean,如Controller、HandlerMapping、HandlerAdapter等等,该初始化上下文应该只加载Web相关组件

其中,DispatcherServlet的继承关系为:

    DispatcherServlet继承FrameworkServlet,FrameworkServlet继承HttpServletBean,HttpServletBean继承至HttpServlet

1、HttpServletBean继承HttpServlet,容器初始化时先调用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");}}
    在其中做的事情包括:

将Servlet初始化参数(init-param)设置到该组件上(如contextAttribute、contextClass、namespace、contextConfigLocation),通过BeanWrapper简化设值过程,方便后续使用;提供给子类初始化扩展点,initServletBean(),该方法由FrameworkServlet覆盖。

2、FrameworkServlet继承HttpServletBean,调用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");}}

/** * 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 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;}

其中做的事包括:初始化web上下文(initWebApplicationContext()方法中调用onRefresh(wac)方法,该方法在子类DispatcherServlet中进行覆盖);设置子类扩展覆盖方法initFrameworkServlet()

从initWebApplicationContext()方法可以看出,基本上如果ContextLoaderListener加载了上下文将作为根上下文(DispatcherServlet的父容器)

3DispatcherServlet继承FrameworkServlet,调用onRefresh()方法

/** * This implementation calls {@link #initStrategies}. */@Overrideprotected void onRefresh(ApplicationContext context) {initStrategies(context);}/** * 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);}
其中做的事情包括初始化默认的Spring Web MVC框架使用的策略(如HandlerMapping)




0 0