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

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: 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全面解析

相关文章
|
1月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
148 1
|
21天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,创建并配置 Spring Boot 项目,实现后端 API;然后,使用 Ant Design Pro Vue 创建前端项目,配置动态路由和菜单。通过具体案例,展示了如何快速搭建高效、易维护的项目框架。
96 62
|
19天前
|
人工智能 前端开发 Java
基于开源框架Spring AI Alibaba快速构建Java应用
本文旨在帮助开发者快速掌握并应用 Spring AI Alibaba,提升基于 Java 的大模型应用开发效率和安全性。
基于开源框架Spring AI Alibaba快速构建Java应用
|
19天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,帮助开发者提高开发效率和应用的可维护性。
37 2
|
1月前
|
人工智能 开发框架 Java
总计 30 万奖金,Spring AI Alibaba 应用框架挑战赛开赛
Spring AI Alibaba 应用框架挑战赛邀请广大开发者参与开源项目的共建,助力项目快速发展,掌握 AI 应用开发模式。大赛分为《支持 Spring AI Alibaba 应用可视化调试与追踪本地工具》和《基于 Flow 的 AI 编排机制设计与实现》两个赛道,总计 30 万奖金。
|
28天前
|
存储 安全 Java
|
1月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用
【10月更文挑战第8天】本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,通过 Spring Initializr 创建并配置 Spring Boot 项目,实现后端 API 和安全配置。接着,使用 Ant Design Pro Vue 脚手架创建前端项目,配置动态路由和菜单,并创建相应的页面组件。最后,通过具体实践心得,分享了版本兼容性、安全性、性能调优等注意事项,帮助读者快速搭建高效且易维护的应用框架。
41 3
|
1月前
|
Java API Spring
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中拦截器的入门教程和实战项目场景实现的详细指南。
26 0
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
|
1月前
|
Java API Spring
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中过滤器的基础知识和实战项目应用的教程。
24 0
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
|
26天前
|
存储 Java 数据管理
强大!用 @Audited 注解增强 Spring Boot 应用,打造健壮的数据审计功能
本文深入介绍了如何在Spring Boot应用中使用`@Audited`注解和`spring-data-envers`实现数据审计功能,涵盖从添加依赖、配置实体类到查询审计数据的具体步骤,助力开发人员构建更加透明、合规的应用系统。