Spring IoC 容器之初始化:Spring IoC 容器的初始化过程在监听器 ContextLoaderListener 类中定义。具体由该类的的 configureAndRefreshwebApplicationContext 方法实现,它包含了两个过程。
配置过程 刷新过程
原理分析下面来看 configureAndRefreshWebApplicationContext 方法的具体实现:
- // 表示容器的标识public static final String CONTEXT_ID_PARAM = "contextId";// 表示容器的配置文件路径public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation";protected void configureAndRefreshWebApplicationContext( ConfigurableWebApplicationContext wac, ServletContext sc) { if (ObjectUtils.identityToString(wac).equals(wac.getId())) { // 配置过程: // 1.设置容器的标识,即 ContextId String idParam = sc.getInitParameter(CONTEXT_ID_PARAM); if (idParam != null) { wac.setId(idParam); }else { wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(sc.getContextPath())); } } // 2.设置容器的 ServletContext wac.setServletContext(sc); // 3.设置容器的配置文件路径,即 ContextConfigLocation String configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM); if (configLocationParam != null) { wac.setConfigLocation(configLocationParam); } // 4.设置容器的环境,并初始化它的属性 ConfigurableEnvironment env = wac.getEnvironment(); // 5.初始化容器的环境属性 if (env instanceof ConfigurableWebEnvironment) { ((ConfigurableWebEnvironment) env).initPropertySources(sc, null); } // 自定义过程,暂不探究 customizeContext(sc, wac); // 刷新过程: wac.refresh();}
Spring 容器的初始化过程实际被细分为了两个过程:配置过程、刷新过程
在 ContextLoaderListener 类中主要完成了配置过程,即设置容器的 ContextId,ServletContext,ConfigLocation,ConfigurableEnvironment 属性等。
刷新的过程则由刚刚创建 Spring 容器自己完成。
配置过程 1. 设置容器的环境Spring 容器在设置的它的 Environment 属性时,如果不存在则默认创建一个 StandardServletEnvironment 对象。具体的继承关系如下:
来看下 getEnvironment 方法:
- private ConfigurableEnvironment environment;
- public ConfigurableEnvironment getEnvironment() { // 不存在,则创建 if (this.environment == null) { this.environment = createEnvironment(); } return this.environment;}protected ConfigurableEnvironment createEnvironment() { return new StandardServletEnvironment();}
再来分析 StandardEnvironment 的初始化过程,该类在初始化过程中,会创建一个 propertySources 对象来保存系统相关的环境变量与属性。
2. 初始化容器的环境属性
- // AbstractEnvironment 类private final MutablePropertySources propertySources = new MutablePropertySources(this.logger);public AbstractEnvironment() { customizePropertySources(this.propertySources); // 省略部分代码...}// StandardEnvironment 类public static final String SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME ="systemEnvironment";public static final String SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME = "systemProperties";protected void customizePropertySources(MutablePropertySources propertySources) { propertySources.addLast( new MapPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties())); propertySources.addLast( new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment()));}
即初始化 Environment 的 propertySources 属性,它会将 ServletContext 、ServletConfig 添加到
propertySources 中。
刷新过程
- // StandardServletEnvironment 类public void initPropertySources(ServletContext servletContext, ServletConfig servletConfig) { // 将 servletContext、servletConfig 添加到 propertySources WebApplicationContextUtils.initServletPropertySources( getPropertySources(),servletContext, servletConfig);}public MutablePropertySources getPropertySources() { return this.propertySources;}
刷新过程由容器自己实现,是个复杂的过程。下一篇再详细分析。
就爱阅读 www.92to.com 网友整理上传, 为您提供最全的知识大全, 期待您的分享,转载请注明出处。
来源: http://www.92to.com/bangong/2017/03-06/18213925.html