该类继承了ContextLoader,并通过contextInitialized方法执行了初始化(传入ServletContext),通过contextDestroyed方法进行资源销毁回收 。重点看ContextLoader方法 。
ContextLoader在初始化时,会先执行内部的一个静态代码块:
private static final Properties defaultStrategies;static {try {ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, ContextLoader.class);defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);}catch (IOException ex) {throw new IllegalStateException("Could not load 'ContextLoader.properties': " + ex.getMessage());}}
这一步会加载classpath下的配置文件ContextLoader.properties,该文件将作为默认配置用于初始化Properties对象defaultStrategies 。
3.1.1. contextInitialized contextInitialized方法的主要内容如下:
文章插图
过程为:
(1) 判断当前Context是否已经初始化过
通过判断ServletContext中是否存在key为org.springframework.web.context.ROOT的值
- 初始化WebApplicationContext:从ContextLoader.properties中查找WebApplicationContext的具体实现,如下:
org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext
即XmlWebApplicationContext,然后初始化该类(2) 配置并刷新该XMLWebApplicationContext
XMLWebApplicationContext继承简图如下:
文章插图
层级比较明显,本身也是一个RefreshableConfigApplicationContext(具体内容可以看往期内容) 。其父类保存了ServletContext和ServletConfig两个Web Context相关的对象,其本身也维持了一些默认属性,如
DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";
这个属性就是默认的Spring配置文件的路径 。需要指出的是XMLWebApplicationContext重写了父类的loadBeanDefinitions方法
@Overrideprotected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {// Create a new XmlBeanDefinitionReader for the given BeanFactory.XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);// Configure the bean definition reader with this context's// resource loading environment.beanDefinitionReader.setEnvironment(getEnvironment());beanDefinitionReader.setResourceLoader(this);beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));// Allow a subclass to provide custom initialization of the reader,// then proceed with actually loading the bean definitions.initBeanDefinitionReader(beanDefinitionReader);loadBeanDefinitions(beanDefinitionReader);}protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {String[] configLocations = getConfigLocations();if (configLocations != null) {for (String configLocation : configLocations) {reader.loadBeanDefinitions(configLocation);}}}@Overrideprotected String[] getDefaultConfigLocations() {//Tip:返回配置文件路径if (getNamespace() != null) {return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX};}else {return new String[] {DEFAULT_CONFIG_LOCATION};}}
这里用了XmlBeanDefinitionReader来解析Bean定义,且指定了配置文件的加载逻辑,getConfigLocations方法:如果父类的configLocations不为空,则返回该值,否则返回getDefaultConfigLocations的值 。而getDefaultConfigLocations方法逻辑为:如果存在命名空间,则返回/WEB_INF/namespace.xml作为配置文件,否则返回/WEB-INF/applicationContext.xml 。对应上面的demo,将返回配置中的文件(同默认值相同) 。XMLWebApplicationContext的初始化步骤为:
- 读取contextId配置,进行设置
- 读取contextConfigLocation配置,使用指定的配置文件,若没有则使用上面提到的默认配置文件DEFAULTCONFIGLOCATION
- 加载contextInitializerClasses指定的class,用于在context刷新前执行自定义处理
- 调用XMLWebApplicationContext的refresh方法
通过将该根Context存在ServletContext中,并设置值为org.springframework.web.context.ROOT,用于第(1)步的判断
3.1.2. contextDestroyed 销毁过程比较简单,首先调用WebApplicationContext的close方法销毁该Context,然后移除ServletContex中的org.springframework.web.context.ROOT属性值,最后清除ServletContext中所有org.springframework.开头的属性值 。
3.2. DispatcherServlet的加载 同ContextLoaderListener类似,DispatcherServlet依赖于Servlet进行扩展 。DispatcherServlet的结构如下:
推荐阅读
- 在淘宝开店流程 淘宝网店怎么开的流程?
- 开淘宝网店的流程 淘宝店铺开设流程
- 淘宝店铺怎么开店流程 淘宝开店的具体操作流程
- 淘宝开店的具体操作流程 开淘宝店的流程和步骤
- 公司名称核准流程是怎么样的 企业名称预先核准申请书
- 茶行业如何利用全流程服务体系实现品牌突围
- ICP许可证申请流程
- 2020淘宝开店流程及费用 开淘宝店要钱吗2020
- 【婚礼流程表】婚礼当天的详细流程表
- 开淘宝店铺需要什么流程 开设淘宝店的主要流程