如何使springbootenviroment拥有PropertySource

发布时间:2021-09-14 11:55:49 作者:柒染
来源:亿速云 阅读:117
# 如何使SpringBoot Environment拥有PropertySource

## 引言

在Spring Boot应用中,`Environment`对象是访问配置属性的核心接口。它通过`PropertySource`机制抽象了不同来源的配置数据(如`.properties`文件、YAML、环境变量等)。理解如何为`Environment`添加自定义`PropertySource`是扩展配置能力的关键技术。

本文将详细介绍三种实现方式,并分析其适用场景。

---

## 一、PropertySource基础概念

### 1.1 什么是PropertySource
`PropertySource`是Spring框架中表示属性源的抽象类,主要实现包括:
- `MapPropertySource`(基于Map的键值对)
- `ResourcePropertySource`(从资源文件加载)
- `SystemEnvironmentPropertySource`(系统环境变量)

### 1.2 Environment的层次结构
Spring Boot的`Environment`采用分层设计:

Environment ├── StandardEnvironment │ ├── System.getProperties() │ └── System.getenv() └── ConfigurableEnvironment (可扩展接口)


---

## 二、添加PropertySource的三种方式

### 2.1 通过@PropertySource注解

```java
@Configuration
@PropertySource(value = "classpath:custom.properties", 
               ignoreResourceNotFound = true)
public class AppConfig {
    // 属性会自动合并到Environment
}

特点: - 适用于静态资源文件 - 不支持YAML格式(需配合YamlPropertySourceLoader) - 无法动态修改

2.2 编程式添加

通过ConfigurableEnvironment接口动态添加:

@SpringBootApplication
public class MyApp implements EnvironmentAware {
    
    @Override
    public void setEnvironment(Environment env) {
        ConfigurableEnvironment cenv = (ConfigurableEnvironment) env;
        Map<String, Object> map = new HashMap<>();
        map.put("custom.key", "value");
        
        PropertySource<?> ps = new MapPropertySource("mySource", map);
        cenv.getPropertySources().addFirst(ps); // 添加到最高优先级
    }
}

适用场景: - 需要运行时动态加载配置 - 从数据库/远程配置中心获取配置

2.3 使用Spring Boot事件机制

通过ApplicationListener在应用启动时注入:

@Component
public class CustomPropertyLoader implements 
        ApplicationListener<ApplicationEnvironmentPreparedEvent> {
            
    @Override
    public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
        PropertySource<?> ps = loadFromRemote();
        event.getEnvironment().getPropertySources().addLast(ps);
    }
}

优势: - 在Environment初始化阶段介入 - 适合需要早于Bean加载的配置


三、优先级与覆盖规则

Spring Boot按以下顺序处理PropertySource(数字越小优先级越高):

  1. 命令行参数(–key=value)
  2. JNDI属性
  3. Java系统属性(System.getProperties())
  4. 操作系统环境变量
  5. 通过random.*生成的随机属性
  6. 应用jar包外的配置文件
  7. 应用jar包内的配置文件
  8. @PropertySource指定的文件
  9. 默认属性(SpringApplication.setDefaultProperties)

重要方法

environment.getPropertySources().addFirst(); // 最高优先级
environment.getPropertySources().addLast();  // 最低优先级

四、实战案例:动态加载数据库配置

@Configuration
public class DbPropertyConfig {
    
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @PostConstruct
    public void init() {
        Map<String, Object> configs = jdbcTemplate.query(
            "SELECT key, value FROM app_config",
            rs -> {
                Map<String, Object> map = new HashMap<>();
                while (rs.next()) {
                    map.put(rs.getString("key"), rs.getString("value"));
                }
                return map;
            });
        
        PropertySource<?> ps = new MapPropertySource("dbConfig", configs);
        ((ConfigurableEnvironment) env).getPropertySources().addAfter(
            "systemEnvironment", ps); // 指定插入位置
    }
}

五、注意事项

  1. 资源释放:自定义PropertySource如果持有资源(如网络连接),需实现Closeable
  2. 性能影响:避免在PropertySource.getProperty()中实现复杂逻辑
  3. Profile过滤:可通过@Profile控制不同环境下的加载行为
  4. 加密配置:建议通过PropertySourcePostProcessor实现解密逻辑

结语

掌握PropertySource的扩展方法能够灵活应对各种配置需求。根据具体场景选择合适的方式: - 简单静态配置 → @PropertySource - 需要动态控制 → 编程式添加 - 早期初始化需求 → 事件监听机制

通过合理设计PropertySource的加载顺序和优先级,可以构建出高度灵活的配置体系。 “`

(全文约750字,涵盖核心实现方案和实际应用场景)

推荐阅读:
  1. Spring Boot自定义配置属性源(PropertySource)
  2. PropertySource注解怎么在Spring boot中使用

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

springboot enviroment propertysource

上一篇:python限定方法参数类型、返回值类型、变量类型等

下一篇:怎么用PHP实现支付宝和微信扫码在线支付的功能

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》