Spring 中的 Environment

时间:2024-11-05 22:22:20

1.Environment

Interface representing the environment in which the current application is running. Models two key aspects of the application environment: profiles and properties. Methods related to property access are exposed via the PropertyResolver superinterface.

一个接口,它代表了当前应用程序运行的环境。这个接口主要建模了应用程序环境的两个关键方面:配置文件(profiles)和属性(properties)。与属性访问相关的方法是通过 PropertyResolver 超级接口暴露出来的。


A profile is a named, logical group of bean definitions to be registered with the container only if the given profile is active. Beans may be assigned to a profile whether defined in XML or via annotations; see the spring-beans 3.1 schema or the @Profile annotation for syntax details. The role of the Environment object with relation to profiles is in determining which profiles (if any) are currently active, and which profiles (if any) should be active by default.
配置文件是一个命名的、逻辑上的bean定义组,这些定义只有在给定配置文件处于激活状态时才会被注册到容器中。无论是在XML中定义还是通过注解指定,都可以将bean分配给配置文件;有关语法详细信息,请参阅spring-beans 3.1模式或@Profile注解。在配置文件方面,Environment 对象的作用是确定哪些配置文件(如果有的话)当前处于激活状态,以及哪些配置文件(如果有的话)应该默认处于激活状态。


Properties play an important role in almost all applications, and may originate from a variety of sources: properties files, JVM system properties, system environment variables, JNDI, servlet context parameters, ad-hoc Properties objects, Maps, and so on. The role of the Environment object with relation to properties is to provide the user with a convenient service interface for configuring property sources and resolving properties from them.
属性在几乎所有应用程序中都扮演着重要角色,并且可能来自多种不同的源:属性文件、JVM系统属性、系统环境变量、JNDI、Servlet上下文参数、临时的Properties对象、Map等。在属性方面,Environment 对象的作用是向用户提供一个方便的服务接口,用于配置属性源并从这些源中解析属性。

/**
 * Interface representing the environment in which the current application is running.
 * Models two key aspects of the application environment: <em>profiles</em> and
 * <em>properties</em>. Methods related to property access are exposed via the
 * {@link PropertyResolver} superinterface.
 *
 * <p>A <em>profile</em> is a named, logical group of bean definitions to be registered
 * with the container only if the given profile is <em>active</em>. Beans may be assigned
 * to a profile whether defined in XML or via annotations; see the spring-beans 3.1 schema
 * or the {@link org.springframework.context.annotation.Profile @Profile} annotation for
 * syntax details. The role of the {@code Environment} object with relation to profiles is
 * in determining which profiles (if any) are currently {@linkplain #getActiveProfiles
 * active}, and which profiles (if any) should be {@linkplain #getDefaultProfiles active
 * by default}.
 *
 * <p><em>Properties</em> play an important role in almost all applications, and may
 * originate from a variety of sources: properties files, JVM system properties, system
 * environment variables, JNDI, servlet context parameters, ad-hoc Properties objects,
 * Maps, and so on. The role of the {@code Environment} object with relation to properties
 * is to provide the user with a convenient service interface for configuring property
 * sources and resolving properties from them.
 *
 * <p>Beans managed within an {@code ApplicationContext} may register to be {@link
 * org.springframework.context.EnvironmentAware EnvironmentAware} or {@code @Inject} the
 * {@code Environment} in order to query profile state or resolve properties directly.
 *
 * <p>In most cases, however, application-level beans should not need to interact with the
 * {@code Environment} directly but instead may have to have {@code ${...}} property
 * values replaced by a property placeholder configurer such as
 * {@link org.springframework.context.support.PropertySourcesPlaceholderConfigurer
 * PropertySourcesPlaceholderConfigurer}, which itself is {@code EnvironmentAware} and
 * as of Spring 3.1 is registered by default when using
 * {@code <context:property-placeholder/>}.
 *
 * <p>Configuration of the {@code Environment} object must be done through the
 * {@code ConfigurableEnvironment} interface, returned from all
 * {@code AbstractApplicationContext} subclass {@code getEnvironment()} methods. See
 * {@link ConfigurableEnvironment} Javadoc for usage examples demonstrating manipulation
 * of property sources prior to application context {@code refresh()}.
 *
 * @author Chris Beams
 * @since 3.1
 * @see PropertyResolver
 * @see EnvironmentCapable
 * @see ConfigurableEnvironment
 * @see AbstractEnvironment
 * @see StandardEnvironment
 * @see org.springframework.context.EnvironmentAware
 * @see org.springframework.context.ConfigurableApplicationContext#getEnvironment
 * @see org.springframework.context.ConfigurableApplicationContext#setEnvironment
 * @see org.springframework.context.support.AbstractApplicationContext#createEnvironment
 */
public interface Environment extends PropertyResolver {

	/**
	 * Return the set of profiles explicitly made active for this environment. Profiles
	 * are used for creating logical groupings of bean definitions to be registered
	 * conditionally, for example based on deployment environment. Profiles can be
	 * activated by setting {@linkplain AbstractEnvironment#ACTIVE_PROFILES_PROPERTY_NAME
	 * "spring.profiles.active"} as a system property or by calling
	 * {@link ConfigurableEnvironment#setActiveProfiles(String...)}.
	 * <p>If no profiles have explicitly been specified as active, then any
	 * {@linkplain #getDefaultProfiles() default profiles} will automatically be activated.
	 * @see #getDefaultProfiles
	 * @see ConfigurableEnvironment#setActiveProfiles
	 * @see AbstractEnvironment#ACTIVE_PROFILES_PROPERTY_NAME
	 */
	String[] getActiveProfiles();

	/**
	 * Return the set of profiles to be active by default when no active profiles have
	 * been set explicitly.
	 * @see #getActiveProfiles
	 * @see ConfigurableEnvironment#setDefaultProfiles
	 * @see AbstractEnvironment#DEFAULT_PROFILES_PROPERTY_NAME
	 */
	String[] getDefaultProfiles();

	/**
	 * Return whether one or more of the given profiles is active or, in the case of no
	 * explicit active profiles, whether one or more of the given profiles is included in
	 * the set of default profiles. If a profile begins with '!' the logic is inverted,
	 * i.e. the method will return {@code true} if the given profile is <em>not</em> active.
	 * For example, {@code env.acceptsProfiles("p1", "!p2")} will return {@code true} if
	 * profile 'p1' is active or 'p2' is not active.
	 * @throws IllegalArgumentException if called with zero arguments
	 * or if any profile is {@code null}, empty, or whitespace only
	 * @see #getActiveProfiles
	 * @see #getDefaultProfiles
	 * @see #acceptsProfiles(Profiles)
	 * @deprecated as of 5.1 in favor of {@link #acceptsProfiles(Profiles)}
	 */
	@Deprecated
	boolean acceptsProfiles(String... profiles);

	/**
	 * Return whether the {@linkplain #getActiveProfiles() active profiles}
	 * match the given {@link Profiles} predicate.
	 */
	boolean acceptsProfiles(Profiles profiles);

}

2.ConfigurableEnvironment

ConfigurableEnvironment 又在 Environment 的基础上多定义了一些对环境进行配置的方法,用于最终的实现类进行配置,还暴露了两个获取 System.getProperties()  和 System.getenv() 的方法

3.AbstractEnvironment

AbstractEnvironment 这个抽象类实现了Environment 和 ConfigurableEnvironment 中定义的绝大部分方法,AbstractEnvironment 实际上就是将 ConfigurablePropertyResolver 进行装饰然后对外暴露,最终关的实现是ConfigurablePropertyResolver来实现的,AbstractEnvironment主要就是提供方法,让外部能够访问ConfigurablePropertyResolver。

4.StandardEnvironment

StandardEnvironment主要就是在 AbstractEnvironment 的基础上,自动初始化了标准的java进程所需要的 Properties

protected void customizePropertySources(MutablePropertySources propertySources) {
	propertySources.addLast(
			new PropertiesPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties()));
	propertySources.addLast(
			new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment()));
}

这个方法是StandardEnvironment 对 AbstractEnvironment中的customizePropertySources()的重写,AbstractEnvironment 是一个空方法没有实现,所以当 AbstractEnvironment 在构造方法中调用 customizePropertySources() 的时候,实际上调用的是 StandardEnvironment 的以上这段代码

 

public class StandardEnvironmentTest {

    public static void main(String[] args) {

        StandardEnvironment standardEnvironment = new StandardEnvironment();

        String userDir = standardEnvironment.getProperty("user.dir");
        System.out.println(userDir);

        String s = standardEnvironment.resolvePlaceholders("aaaa ${user.dir} bbbbb");

        System.out.println(s);

    }

}

运行结果:
D:\springboot-demo\study-spring
aaaa D:\springboot-demo\study-spring bbbbb