zoukankan      html  css  js  c++  java
  • 03.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 对象来保存系统相关的环境变量与属性。

    // 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()));
    }

    2.初始化容器的环境属性

    即初始化 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;
    }
  • 相关阅读:
    用python3实现AES/CBC/PKCS5padding算法加解密
    python之逆向某贷款app破解sign参数
    用Python实现RSA签名和验签
    python3 RSA 长字符串分段加密解密
    PyCharm 字体大小颜色常用功能设置
    pycharm2019.3/pycharm2020.2 专业版 安装教程永久激活
    Android 四大组件和Intent
    Linux的查找命令
    Linux(centos)系统各个目录的作用详解
    linux ls文件颜色和底色设置
  • 原文地址:https://www.cnblogs.com/moxiaotao/p/9349584.html
Copyright © 2011-2022 走看看