springboot属性注入增强(一)背景/需求

一 背景

springboot 在启动时候会将系统的环境变量、项目的启动时设置的属性 、application.yml文件(或application.properties文件)、@PropertySource定义的配置文件中的属性加载到Environment对象中,分布式配置中心框架也会把配置加载到Environment中。而springboot的属性注入即@Value、@ConfigurationProperties、xml文件的${.....},就是从Environment拿的数据,再进行解析的,我们要做的就是对Environment的数据源添加自定义的数据和解析过程中执行我们自定义的解析代码。

二 详细需求

1 根据配置中的内容,动态的添加自定义的配置

如配置文件中只配置了一个用户的id,启动时根据这个id去获取用户信息,并把获取到的信息添加到springboot的配置中,也就是定制我们自己获取属性的方式。这样启动后就能直接用到这个id对应的用户姓名、性别等数据(不可变的数据,可变的数据就涉及到配置动态刷新了,后面再讲),无需再手动调用接口获取。效果如下

1.1 application.yml文件中配置用户id

复制代码
user:
  id: 123

1.2 通过这个用户id "123"来使用这个用户的相关信息

1.2.1 @Value
复制代码
    @Value("${user.123.name}")
    private String user123Name;

    @Value("${user.123.sex}")
    private String user123Age;
1.2.2 @ConfigurationProperties
复制代码
@Data
@Component
@ConfigurationProperties(prefix = "user.123")
public class UserConfiguration {
    /**
     * 姓名
     */
    private String name;

    /**
     * 性别
     */
    private String sex;
}

    @Autowired
    private UserConfiguration userConfiguration;
1.2.3 Environment
复制代码
    @Autowired
    private Environment environment;

    public void configTest() {
        String user123Age = environment.getProperty("user.123.sex");
        String user123Name = environment.getProperty("user.123.name");
    }

2 自定义属性解析方法

如希望对一个配置文件中的属性执行我们自定义的方法,让实际使用这个属性的时候,用的是这个方法转换后的属性,如我配置了一个加密的属性,想通过一个方法解密,使得使用时就是明文

复制代码
spring:
  redis:
    password: decode(abc123)

这个decode就是我们自定义的方法,方法的入参是一个密文,通过这个abc123可以获取到实际的密码。

具体的使用场景如下

  1. 在不改变属性名的情况下,对已有的配置做一个增强比如上述说的解密或者追加、替换一些字符,如整合redis的时候需要的密码,不想直接暴漏到项目中,因为属性名是肯定不能变的(redis根据属性名来找属性的),那么就可以自定义一个解密方法来将他的属性值进行解密。

2.将属性值改为之前不存在的属性,如上述1.2中动态新增的属性,当然可以直接这样用

复制代码
spring:
  redis:
    password: ${user.123.name}

,但如果是在执行org.springframework.context.support.PropertySourcesPlaceholderConfigurer#postProcessBeanFactory后添加进去的,那么springboot会找不到这个user.123.name属性,是会直接报错的(ignoreUnresolvablePlaceholders = false时,默认就是false),所以可以自定义一个函数先越过这个校验,在后面再进行真正的赋值。

复制代码
spring:
  redis:
    password: getPassword(user.123.name)

不过这个场景比较鸡肋,因为只要我们控制好动态新增属性的时机那么就完全可以直接用${...}来替换

相关推荐
用户398346161208 小时前
Go-Spring 实战第 15 课 —— Condition:根据配置和上下文激活 Bean
spring·go
凤山老林8 小时前
DDD(领域驱动设计)在复杂业务系统中的落地指南
java·开发语言·数据库·ddd·领域驱动
JEECG低代码平台8 小时前
JimuChatBI — 首款免费开源的 Java 智能问数ChatBI平台,零成本接入,AI对话式智能分析
java·人工智能·开源·aigc·人工智能低代码
霸道流氓气质9 小时前
SpringBoot中使用Spring AI框架集成本地Ollama实现AI快速对话完整示例
人工智能·spring boot·spring
星梦清河9 小时前
Java—异步编程
java·开发语言
GIS数据转换器9 小时前
智慧能源管理平台
java·大数据·运维·人工智能·无人机
garmin Chen9 小时前
LeetcodeHot100打卡(14、合并空间,15、轮转数组,16、除了自身以外数组乘积,17.缺失的第一个整数)
java·笔记·学习·算法
接着奏乐接着舞9 小时前
dto 转entity方法
java·开发语言
我命由我123459 小时前
Android 开发问题:项目同时引入了两个包含相同类文件的库(AndroidX 库、旧版本支持库),导致了重复类错误
android·java·java-ee·android studio·android-studio·androidx·android runtime
梓色系10 小时前
Spring AI 实战:从零搭建 MCP 客户端与服务端,让大模型拥有“手脚“
java·人工智能·spring