Spring源码解析-Web容器启动过程
2017-11-17 01:40
761 查看
Web容器启动过程,主要讲解Servlet和Spring容器结合的内容。
流程图如下:
Web容器启动的Root Context是有ContextLoaderListener,一般使用spring,都会在web.xml中配置这个监听器。
下面就从这里入手,看看它是如何启动spring容器。
这个类继承了ContextLoader,同时实现了ServletContextListener,从注释上可以看出,web应用会调用contextInitalized方法进行初始化。
先看一下ServletContextListener.
从名字可以看出,一个是初始化方法,另一个是销毁是调用的方法。
回到上面而initWebApplicationContext方法,通过createWebApplicationContext方法获取WebApplicationContext,调用determineContextClass方法如下:
从注释上可以看出返回的是XmlWebApplicationContext。
回到initWebApplicationContext方法中,有一段
会调用configureAndRefreshWebApplication方法,感觉是配置和刷新,进入方法。
至此,通过wac.refresh()启动Spring容器。
流程图如下:
Web容器启动的Root Context是有ContextLoaderListener,一般使用spring,都会在web.xml中配置这个监听器。
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
下面就从这里入手,看看它是如何启动spring容器。
public class ContextLoaderListener extends ContextLoader implements ServletContextListener { public ContextLoaderListener(WebApplicationContext context) { super(context); } /** * Initialize the root web application context. */ @Override public void contextInitialized(ServletContextEvent event) { initWebApplicationContext(event.getServletContext()); } /** * Close the root web application context. */ @Override public void contextDestroyed(ServletContextEvent event) { closeWebApplicationContext(event.getServletContext()); ContextCleanupListener.cleanupAttributes(event.getServletContext()); } }
这个类继承了ContextLoader,同时实现了ServletContextListener,从注释上可以看出,web应用会调用contextInitalized方法进行初始化。
先看一下ServletContextListener.
public interface ServletContextListener extends EventListener { void contextInitialized(ServletContextEvent var1); void contextDestroyed(ServletContextEvent var1); }
从名字可以看出,一个是初始化方法,另一个是销毁是调用的方法。
回到上面而initWebApplicationContext方法,通过createWebApplicationContext方法获取WebApplicationContext,调用determineContextClass方法如下:
/** * Return the WebApplicationContext implementation class to use, either the * default XmlWebApplicationContext or a custom context class if specified. * @param servletContext current servlet context * @return the WebApplicationContext implementation class to use * @see #CONTEXT_CLASS_PARAM * @see org.springframework.web.context.support.XmlWebApplicationContext */ protected Class<?> determineContextClass(ServletContext servletContext) { String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM); if (contextClassName != null) { try { return ClassUtils.forName(contextClassName, ClassUtils.getDefaultClassLoader()); } catch (ClassNotFoundException ex) { throw new ApplicationContextException( "Failed to load custom context class [" + contextClassName + "]", ex); } } else { contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName()); try { return ClassUtils.forName(contextClassName, ContextLoader.class.getClassLoader()); } catch (ClassNotFoundException ex) { throw new ApplicationContextException( "Failed to load default context class [" + contextClassName + "]", ex); } } }
从注释上可以看出返回的是XmlWebApplicationContext。
回到initWebApplicationContext方法中,有一段
if (this.context instanceof ConfigurableWebApplicationContext) { ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context; 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 -> // determine parent for root web application context, if any. ApplicationContext parent = loadParentContext(servletContext); cwac.setParent(parent); } configureAndRefreshWebApplicationContext(cwac, servletContext); } }
会调用configureAndRefreshWebApplication方法,感觉是配置和刷新,进入方法。
protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) { if (ObjectUtils.identityToString(wac).equals(wac.getId())) { // The application context id is still set to its original default value // -> assign a more useful id based on available information String idParam = sc.getInitParameter(CONTEXT_ID_PARAM); if (idParam != null) { wac.setId(idParam); } else { // Generate default id... wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(sc.getContextPath())); } } wac.setServletContext(sc); //获取配置的参数信息 String configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM); if (configLocationParam != null) { wac.setConfigLocation(configLocationParam); } // The wac environment's #initPropertySources will be called in any case when the context // is refreshed; do it eagerly here to ensure servlet property sources are in place for // use in any post-processing or initialization that occurs below prior to #refresh ConfigurableEnvironment env = wac.getEnvironment(); if (env instanceof ConfigurableWebEnvironment) { ((ConfigurableWebEnvironment) env).initPropertySources(sc, null); } customizeContext(sc, wac); //刷新上下文-->AbsreactApplicationContext.refresh() wac.refresh(); }
至此,通过wac.refresh()启动Spring容器。
相关文章推荐
- (Spring源码解析)一步一步分析,springMVC项目启动过程(二)
- (Spring源码解析)一步一步分析,springMVC项目启动过程(一)
- spring源码分析-应用启动过程
- Spring源码分析----IOC容器的实现(IoC容器的初始化过程(定位、载入解析、注册))
- OpenStack Cinder服务启动过程中的资源加载和扩展源码解析之三
- [Spring Boot] 1. Spring Boot启动过程源码分析
- 【Spring源码分析系列】启动component-scan类扫描加载过程
- spring IOC源码之解析xml中各个元素的过程
- spring 实现IOC过程源码解析<一>
- Spring源码解析之:Spring Security启动细节和工作模式
- Spring Boot 2.x 启动全过程源码分析(上)入口类剖析
- spring启动component-scan类扫描加载过程---源码分析
- Spring源码解析二:IOC容器初始化过程详解
- spring启动过程之源码跟踪(续beanfactory)--spring Debug
- spring启动component-scan类扫描加载过程---源码分析
- Spring Boot启动过程源码分析(二)事件监听器
- spring启动component-scan类扫描加载过程---源码分析
- Android源码解析四大组件系列(二)---Activity启动过程的总体把握
- Android源码解析之Zygote启动过程的源代码分析
- Spring源码解析:默认标签的解析过程