Spring揭秘:Environment接口应用场景及实现原理!

简介: Environment接口提供了强大且灵活的环境属性管理能力,通过它,开发者能轻松地访问和配置应用程序运行时的各种属性,如系统属性、环境变量等。同时,Environment接口还支持属性源的定制和扩展,使得开发者能根据实际需求灵活地定制属性的加载和解析方式。

Spring揭秘:Environment接口应用场景及实现原理! - 程序员古德

内容概要

Environment接口提供了强大且灵活的环境属性管理能力,通过它,开发者能轻松地访问和配置应用程序运行时的各种属性,如系统属性、环境变量等。

同时,Environment接口还支持属性源的定制和扩展,使得开发者能根据实际需求灵活地定制属性的加载和解析方式。

核心概念

它能解决了什么问题?

Environment接口在Spring框架主要负责管理和提供应用程序运行时的环境信息,这些信息包括但不限于系统属性、环境变量、命令行参数、配置文件属性等。

以下是Environment接口主要用来解决的一些技术问题:

  1. 属性管理Environment提供了访问应用程序属性的集中机制,可以使用它来读取、设置和管理这些属性,这些属性可以来自不同的源,如系统属性、环境变量、配置文件(如properties或yml文件)等。
  2. 配置灵活性:通过使用Environment,开发者可以在运行时动态地改变或覆盖配置,这增加了配置的灵活性和可定制性,对于需要根据不同环境(如开发、测试、生产等)进行不同配置的应用程序来说尤为重要。
  3. 简化配置访问:在Spring应用程序中,可能需要访问各种配置值,Environment简化了这一过程,通过提供统一且易于使用的API,可以轻松地从代码中访问这些配置值。
  4. 配置源整合:Spring的Environment能够将来自不同源的配置信息整合到一起,提供了一个统一的视图来访问这些配置,这意味着,无论配置信息是存储在系统属性、环境变量还是配置文件中,都可以使用相同的方式来访问它们。
  5. 属性占位符解析Environment还支持属性占位符的解析,这允许在配置中使用占位符来引用其他属性的值,这对于创建基于其他属性值的配置特别有用。
  6. 支持Spring表达式语言:在一些高级用例中,可能需要使用Spring表达式语言(SpEL)来访问或操作配置数据。Environment与SpEL的集成使得这种操作变得更加简单和直接。

它有哪些子类拓展

image-20240311193232629

如上图所示,Environment接口有多个实现类,这些实现类根据用途和配置源的不同而有所区分,以下是Environment接口的一些主要实现类:

  1. StandardEnvironment
    这是Environment接口的最基本实现,用于非Web应用程序,它主要管理JVM级别的系统属性和环境变量,通常,在创建独立的Java应用程序或命令行工具时会使用StandardEnvironment
  2. StandardServletEnvironment
    这是用于基于Servlet的Web应用程序的Environment实现,除了系统属性和环境变量外,它还考虑了Servlet规范定义的配置参数,如Servlet上下文初始化参数和JNDI属性,在Spring MVC应用程序中,通常会使用StandardServletEnvironment
  3. ConfigurableEnvironment
    这是一个可以配置和修改的Environment实现,它通常用作其他更具体环境实现的基类,如StandardEnvironmentAbstractEnvironment。它允许添加、删除或修改属性源(PropertySource)。
  4. ConfigurableWebEnvironment:提供了一个专门用于Web应用程序的环境接口,它扩展了ConfigurableEnvironment接口,这个接口的主要作用是为Web应用程序提供配置环境的能力,同时添加了一些与Web环境相关的特性。

个人思考

ConfigurableEnvironmentConfigurableWebEnvironment有什么区别?

他们都是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揭秘:Aware接口应用场景及实现原理!

Spring揭秘:@import注解应用场景及实现原理!

Spring揭秘:ImportBeanDefinitionRegistrar应用场景及实现原理!

Java并发基础:原子类之AtomicMarkableReference全面解析!

Java并发基础:concurrent Flow API全面解析

相关文章
|
9天前
|
Java API 微服务
【Spring Boot系列】通过OpenAPI规范构建微服务服务接口
【4月更文挑战第5天】通过OpenAPI接口构建Spring Boot服务RestAPI接口
|
1天前
|
XML Java 数据格式
手写spring第八章-定义标记类型Aware接口,实现感知容器对象
手写spring第八章-定义标记类型Aware接口,实现感知容器对象
4 0
|
1月前
ssm(Spring+Spring mvc+mybatis)Dao接口——IDeptDao
ssm(Spring+Spring mvc+mybatis)Dao接口——IDeptDao
8 0
|
1月前
|
Java Spring
使用JDBCTemplate实现与Spring结合,方法公用 ——接口(BaseDao)
使用JDBCTemplate实现与Spring结合,方法公用 ——接口(BaseDao)
9 0
|
1月前
|
存储 Java 数据处理
Spring揭秘:ClassPathScanningProvider接口应用场景及实现原理!
ClassPathScanningCandidateComponentProvider是Spring框架中一个非常核心的类,它主要用于在类路径下扫描并发现带有特定注解的组件,支持诸如@ComponentScan、@Component、@Service、@Repository和@Controller等注解的自动扫描和注册。
Spring揭秘:ClassPathScanningProvider接口应用场景及实现原理!
|
1月前
|
Java API 开发者
Spring揭秘:BeanDefinitionBuilder接口应用场景及实现原理!
BeanDefinitionBuilder类为Spring框架中的Bean定义提供了灵活且强大构建方式,通过API,开发者能够轻松创建和配置Bean,无需依赖繁琐的XML配置或注解。
Spring揭秘:BeanDefinitionBuilder接口应用场景及实现原理!
|
30天前
|
Java 应用服务中间件 Maven
SpringBoot 项目瘦身指南
SpringBoot 项目瘦身指南
44 0
|
2月前
|
缓存 Java Maven
Spring Boot自动配置原理
Spring Boot自动配置原理
48 0
|
1月前
|
缓存 安全 Java
Spring Boot 面试题及答案整理,最新面试题
Spring Boot 面试题及答案整理,最新面试题
113 0