• spring默认启动位置以及contextConfigLocation设置源码解析


    spring默认启动位置以及contextConfigLocation设置源码解析

    这几天在看spring的源码,涉及到spring启动位置的部分,下面就看看spring到底是从哪儿开始加载的。本文使用的是spring3.0M3

    首先spring的加载会借助一个监听器ContextLoaderListener,直接上web.xml文件

        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
    
    • 1
    • 2
    • 3
    • 4

    我们通常会对加载位置统一管理

     <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                /WEB-INF/conf/spring/**/*.xml
            </param-value>
    </context-param>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    这个org.springframework.web.context.ContextLoaderListener类型是springframework中的原始加载上下文的监听器, 
    通常我们会自定义一个Listener去继承ContextLoaderListener并另外实现我们需要初始化的接口(通常我们会选择实现一些接口来对session的管理)

    public class FrameServletContextListener extends ContextLoaderListener implements ServletContextListener,HttpSessionAttributeListener,HttpSessionListener {
        //
        private ServletContext initPath(ServletContextEvent event) {
    
        }
    
            public synchronized void contextDestroyed(ServletContextEvent event) {
        //
        }
    
        ...
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    当监听器设置好了之后 ,启动web容器 监听器开始启动ContextLoaderListenerl 
    类中的方法contextInitialized()

        /**
         * Initialize the root web application context.
         */
        public void contextInitialized(ServletContextEvent event) {
            this.contextLoader = createContextLoader();
            if (this.contextLoader == null) {
                this.contextLoader = this;
            }
            this.contextLoader.initWebApplicationContext(event.getServletContext());
        }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    这样this.contextLoader.initWebApplicationContext(event.getServletContext());ContextLoaderListener 
    就会借助容器的上下文去初始一个spring的应用上下文,使用到了ContextLoader这个类 。

    在ContextLoader初始化时我们看到这样一块static代码

        static {
            // Load default strategy implementations from properties file.
            // This is currently strictly internal and not meant to be customized
            // by application developers.
            try {
                //这一句会去加载同在此包下的一个properties文件的值(ContextLoader.properties)
                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());
            }
        }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    属性文件中这样定义 
    引用 
    org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext 
    这样我们就能根据属性文件中的定义反射出一个XmlWebApplicationContext上下文了

    然而我们在XmlWebApplicationContext中看到如下变量

        /** Default config location for the root context */
        public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";
    • 1
    • 2

    至此我们已经知道默认加载spring文件的启动位置了,当我们再看ContextLoader类,我们就会看到传说中的参数contextConfigLocation

        public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation";
    • 1

    而XmlWebApplicationContext对象正是调用了这个参数去设置启动位置

        wac.setConfigLocation(servletContext.getInitParameter(CONFIG_LOCATION_PARAM));
    • 1

    再往上看XmlWebApplicationContext继承的AbstractRefreshableConfigApplicationContext类中的setConfigLocation方法将此抽象类中的String[] configLocations值填充

    并在AbstractRefreshableConfigApplicationContext类中我们看到spring对默认启动文件位置和配置启动文件位置的支持

        protected String[] getConfigLocations() {
            return (this.configLocations != null ? this.configLocations : getDefaultConfigLocations());
        } 
    • 1
    • 2
    • 3

    至此我们已经清楚spring将从哪儿加载并知道加载哪些文件了。

  • 相关阅读:
    我的2015技术学习流水账
    Java程序员的现代RPC指南
    我对读计算机软件专业硕士的几点看法
    Hadoop加速器GridGain
    BDD敏捷开发入门与实战
    openstack kilo部署-基础环境
    python学习之成员信息增删改查
    网站监控系统安装部署(zabbix,nagios)
    监控redis数据库应用状态:python,tornado实现
    python 远程执行命令、发布文件
  • 原文地址:https://www.cnblogs.com/Jeely/p/10762000.html
Copyright © 2020-2023  润新知