内容概要
Environment
接口提供了强大且灵活的环境属性管理能力,通过它,开发者能轻松地访问和配置应用程序运行时的各种属性,如系统属性、环境变量等。
同时,Environment接口还支持属性源的定制和扩展,使得开发者能根据实际需求灵活地定制属性的加载和解析方式。
核心概念
它能解决了什么问题?
Environment
接口在Spring框架主要负责管理和提供应用程序运行时的环境信息,这些信息包括但不限于系统属性、环境变量、命令行参数、配置文件属性等。
以下是Environment
接口主要用来解决的一些技术问题:
- 属性管理:
Environment
提供了访问应用程序属性的集中机制,可以使用它来读取、设置和管理这些属性,这些属性可以来自不同的源,如系统属性、环境变量、配置文件(如properties或yml文件)等。 - 配置灵活性:通过使用
Environment
,开发者可以在运行时动态地改变或覆盖配置,这增加了配置的灵活性和可定制性,对于需要根据不同环境(如开发、测试、生产等)进行不同配置的应用程序来说尤为重要。 - 简化配置访问:在Spring应用程序中,可能需要访问各种配置值,
Environment
简化了这一过程,通过提供统一且易于使用的API,可以轻松地从代码中访问这些配置值。 - 配置源整合:Spring的
Environment
能够将来自不同源的配置信息整合到一起,提供了一个统一的视图来访问这些配置,这意味着,无论配置信息是存储在系统属性、环境变量还是配置文件中,都可以使用相同的方式来访问它们。 - 属性占位符解析:
Environment
还支持属性占位符的解析,这允许在配置中使用占位符来引用其他属性的值,这对于创建基于其他属性值的配置特别有用。 - 支持Spring表达式语言:在一些高级用例中,可能需要使用Spring表达式语言(SpEL)来访问或操作配置数据。
Environment
与SpEL的集成使得这种操作变得更加简单和直接。
它有哪些子类拓展
如上图所示,Environment
接口有多个实现类,这些实现类根据用途和配置源的不同而有所区分,以下是Environment
接口的一些主要实现类:
- StandardEnvironment:
这是Environment
接口的最基本实现,用于非Web应用程序,它主要管理JVM级别的系统属性和环境变量,通常,在创建独立的Java应用程序或命令行工具时会使用StandardEnvironment
。 - StandardServletEnvironment:
这是用于基于Servlet的Web应用程序的Environment
实现,除了系统属性和环境变量外,它还考虑了Servlet规范定义的配置参数,如Servlet上下文初始化参数和JNDI属性,在Spring MVC应用程序中,通常会使用StandardServletEnvironment
。 - ConfigurableEnvironment:
这是一个可以配置和修改的Environment
实现,它通常用作其他更具体环境实现的基类,如StandardEnvironment
和AbstractEnvironment
。它允许添加、删除或修改属性源(PropertySource
)。 - ConfigurableWebEnvironment:提供了一个专门用于Web应用程序的环境接口,它扩展了
ConfigurableEnvironment
接口,这个接口的主要作用是为Web应用程序提供配置环境的能力,同时添加了一些与Web环境相关的特性。
个人思考
ConfigurableEnvironment
和ConfigurableWebEnvironment
有什么区别?
他们都是Spring框架中用于配置和管理应用程序运行环境的接口,然而,它们之间存在一些关键的区别,主要在于它们的应用场景和提供的功能:
1、应用场景
ConfigurableEnvironment
:这是Spring框架中用于配置和管理通用应用程序环境的接口,它可以用于任何类型的应用程序,无论是Web应用程序还是非Web应用程序。ConfigurableWebEnvironment
:这个接口是专门为Web应用程序设计的,用于配置和管理Web应用程序的运行环境,它扩展了ConfigurableEnvironment
接口,添加了一些与Web环境相关的特性。然而,需要注意的是,在较新版本的Spring框架中(如Spring 5及以后),ConfigurableWebEnvironment
接口实际上已经被废弃,而推荐使用ConfigurableEnvironment
来处理Web和非Web环境的配置,但在旧版本的Spring中,这个接口仍然存在并用于区分Web和非Web环境。
2、提供的功能
ConfigurableEnvironment
:这个接口提供了一组方法来配置和管理应用程序的环境属性,可以通过它添加、删除或修改属性源,并定制属性的检索顺序,此外,它还提供了访问和修改系统属性、环境变量等功能。ConfigurableWebEnvironment
:除了继承自ConfigurableEnvironment
的所有功能外,这个接口还提供了对Servlet上下文初始化参数的访问,这是Web应用程序特有的功能,允许在Web应用程序的运行环境中访问和修改Servlet上下文的初始化参数,由于该接口在较新版本的Spring中已被废弃,因此在实际开发中可能不会直接使用它。
代码案例
下面代码演示了几个使用频率较高的Environment代码案例。
StandardEnvironment案例
下面是一个简单的Java代码示例,演示了如何使用org.springframework.core.env.StandardEnvironment
类。
这个示例创建了一个StandardEnvironment
实例,并通过它访问了系统属性和环境变量。
import org.springframework.core.env.StandardEnvironment;
public class StandardEnvironmentExample {
public static void main(String[] args) {
// 创建一个StandardEnvironment实例
StandardEnvironment environment = new StandardEnvironment();
// 获取系统属性"java.version"
String javaVersion = environment.getSystemProperties().getProperty("java.version");
System.out.println("Java Version: " + javaVersion); // 输出Java版本信息
// 获取环境变量"PATH"(注意:环境变量的名称可能因操作系统而异)
String pathVariable = environment.getSystemEnvironment().get("PATH");
// 在Windows上,PATH环境变量的分隔符是";",在Unix/Linux上是":"
String pathSeparator = System.getProperty("path.separator");
if (pathVariable != null) {
System.out.println("PATH Environment Variable (first entry): " + pathVariable.split(pathSeparator)[0]);
// 输出PATH环境变量的第一个条目(根据路径分隔符分割后)
} else {
System.out.println("PATH Environment Variable is not set.");
}
// 尝试获取一个不存在的系统属性或环境变量将返回null
String nonExistentProperty = environment.getSystemProperties().getProperty("non.existent.property");
System.out.println("Non-Existent Property: " + nonExistentProperty); // 输出null或未定义属性的信息
}
}
在这段代码中,创建了一个StandardEnvironment
的实例,然后,使用getSystemProperties()
方法获取系统属性,并通过getProperty()
方法获取特定的属性(在这个例子中是"java.version"
)。
类似地,使用getSystemEnvironment()
方法获取环境变量,并通过get()
方法获取特定的环境变量(在这个例子中是"PATH"
)。请注意,环境变量的名称和可用性可能因操作系统而异。
注意,如果是非Web应用程序则推荐使用StandardEnvironment
,如果是Web应用程序,则推荐使用StandardServletEnvironment
。
ConfigurableEnvironment案例
下面是一个使用org.springframework.core.env.ConfigurableEnvironment
类的Java代码示例。
在这个示例中,创建一个ConfigurableEnvironment
实例,并向其添加自定义的属性源。=,然后,将演示如何从环境中检索这些属性。
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.Environment;
import java.util.HashMap;
import java.util.Map;
public class ConfigurableEnvironmentExample {
public static void main(String[] args) {
// 创建一个ConfigurableEnvironment实例
ConfigurableEnvironment environment = new ConfigurableEnvironment();
// 创建一个包含自定义属性的Map
Map<String, Object> customProperties = new HashMap<>();
customProperties.put("custom.property.one", "Value One");
customProperties.put("custom.property.two", "Value Two");
// 创建一个属性源,并命名为"customProperties"
MapPropertySource customPropertySource = new MapPropertySource("customProperties", customProperties);
// 将自定义属性源添加到环境中
environment.getPropertySources().addLast(customPropertySource);
// 从环境中检索自定义属性并打印它们
String propertyOne = environment.getProperty("custom.property.one");
String propertyTwo = environment.getProperty("custom.property.two");
System.out.println("Custom Property One: " + propertyOne); // 输出: Custom Property One: Value One
System.out.println("Custom Property Two: " + propertyTwo); // 输出: Custom Property Two: Value Two
// 尝试获取一个不存在的属性将返回null
String nonExistentProperty = environment.getProperty("non.existent.property");
System.out.println("Non-Existent Property: " + nonExistentProperty); // 输出: Non-Existent Property: null
}
}
在这段代码中,创建了一个ConfigurableEnvironment
实例,然后,创建了一个包含自定义属性的Map
,并使用这个Map
创建了一个MapPropertySource
实例,将这个自定义属性源命名为"customProperties"
,并将其添加到环境的属性源列表的末尾。
接着,使用environment.getProperty()
方法从环境中检索自定义属性,并将它们打印到控制台。最后,尝试获取一个不存在的属性,以演示当属性不存在时返回null
的情况。
END!
END!
END!
往期回顾
精品文章
Spring揭秘:ImportBeanDefinitionRegistrar应用场景及实现原理!