spring-core组件详解——Environment应用上下文环境

丶灬走出姿态 提交于 2020-03-02 15:22:59

环境代表当前应用运行时所处的环境。

整个应用环境模型包括2个关键方面:

  1. profiles配置组(以下简称组):
    一个profile组,是一个以name名称命名的、逻辑上的、要被注册到容器中的BeanDefinition的集合。简单一点说,一个profile就代表一组BeanDefinition,这个对应配置文件中<beans profile="">。当加载解析xml配置文件的时候,只有active=true激活的BeanDefinition才会被加载进容器。

  2. properties环境变量:
    在几乎所有的应用中,Properties环境变量都扮演着非常重要的角色,且这些变量值可以来自于各种PropertySource属性源,如:properties文件、jvm虚拟机环境变量、操作系统环境变量、JNDI、Servlet上下文参数、自定义的属性对象、Map对象,等等。Environment环境对象为用户提供了方便的接口,用于配置和使用属性源。

环境体系图如下:

刚才提到环境模型具有2个关键方面:profiles和properties,从体系图中可以看出,properties方面的所有功能由PropertyResolver属性解决器来实现,环境模型只是通过装饰模式,在PropertyResolver功能的基础上,额外扩展出了profiles方面的功能。因此在接口方面,Environment继承自PropertyResolver,从实现类方面,AbstractEnvironment类内部持有一个PropertySourcesPropertyResolver类型对象的引用。

关于PropertyResolver,我前边的文章已经进行了详细的解释,因此在本文中,我们重点关注环境模型在profiles方面的实现原理,体系图如下:

  1. Environment接口:

    public interface Environment extends PropertyResolver {
    
    	/**
    	 * 获取当前环境对象激活的所有profile组。
    	 * 
    	 * @return
    	 */
    	String[] getActiveProfiles();
    
    	/**
    	 * 获取默认的profile组。
    	 * 如果当前环境对象中激活的组为空(getActiveProfiles()返回空数组)的话,
    	 * 则会启用默认profile组。
    	 * 
    	 * @return
    	 */
    	String[] getDefaultProfiles();
    	
    	/**
    	 * 判断给定的一个或多个组中,是否存在满足当前环境对象配置的组(任意一个组满足即可)。
    	 * 如:
    	 * 调用acceptsProfiles("p1","!p2"),如果当前环境对象激活了p1,
    	 * 或者没有激活p2(注意是或,满足一个条件即可),则返回true,否则返回false。
    	 * 
    	 * @param profiles
    	 * @return
    	 */
    	boolean acceptsProfiles(String... profiles);
    
    }
  2. ConfigurableEnvironment:

    public interface ConfigurableEnvironment extends Environment, ConfigurablePropertyResolver {
    
    	/**
    	 * 重新设置激活的组集合。
    	 * @param profiles
    	 */
    	void setActiveProfiles(String... profiles);
    
    	/**
    	 * 向当前激活的组集合中添加一个组。
    	 * @param profile
    	 */
    	void addActiveProfile(String profile);
    
    	/**
    	 * 设置默认激活的组集合。激活的组集合为空时会使用默认的组集合。
    	 * 
    	 * @param profiles
    	 */
    	void setDefaultProfiles(String... profiles);
    
    	/**
    	 * 获取当前环境对象中的属性源集合,也就是应用环境变量。
    	 * 属性源集合其实就是一个容纳PropertySource的容器。
    	 * 这个方法提供了直接配置属性源的入口。
    	 * @return
    	 */
    	MutablePropertySources getPropertySources();
    
    	/**
    	 * 获取操作系统环境变量
    	 * 这个方法提供了直接配置系统环境变量的入口。
    	 * @return
    	 */
    	Map<String, Object> getSystemEnvironment();
    
    	/**
    	 * 获取虚拟机环境变量
    	 * 这个方法提供了直接配置虚拟机环境变量的入口。
    	 * @return
    	 */
    	Map<String, Object> getSystemProperties();
    
    	/**
    	 * 合并指定环境对象中的配置到当前环境对象中。
    	 * @param parent
    	 */
    	void merge(ConfigurableEnvironment parent);
    
    }
  3. AbstractEnvironment抽象基类:
    该类实际上实现了以上接口的所有方法,且额外扩展了自定义属性源的入口:
            protected void customizePropertySources(MutablePropertySources propertySources);
    但是因为初始时属性源集合只是一个空集合,没有任何意义,因为该类定义为抽象基类,不能直接实例化使用。部分代码如下:

    /**
     * 部分代码
     * @author lixin
     *
     */
    public class AbstractEnvironment {
    	/**
    	 * 可变属性源集合
    	 */
    	private final MutablePropertySources propertySources = new MutablePropertySources();
    	
    	/**
    	 * 在构造方法中直接调用自定义属性源集合
    	 */
    	public AbstractEnvironment() {
    		customizePropertySources(this.propertySources);
    		
    	}
    	
    	/**
    	 * 自定义属性源集合,
    	 * 默认空实现,子类可重写,用来配置属性源。
    	 * 
    	 * @param propertySources
    	 */
    	protected void customizePropertySources(MutablePropertySources propertySources) {
    	}
    }
  4. StandardEnvironment:
    该类定义了Spring应用运行时使用的标准环境,其实就是重写了customizePropertySources方法,先后追加了jvm虚拟机环境变量属性源和操作系统环境变量属性源这两个属性源。当然对于特殊的spring运行环境,我们可以创建标准环境的子类,以实现属性源的扩充,比如:StandardServletEnvironment类,用于web应用环境。

    public class StandardEnvironment extends AbstractEnvironment {
    
    	// 操作系统环境变量属性源的名称
    	public static final String SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME = "systemEnvironment";
    
    	// jvm虚拟机系统环境变量属性源的名称
    	public static final String SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME = "systemProperties";
    
    	@Override
    	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()));
    	}
    
    }

        以上就是spring框架的基本环境体系。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!