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)

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

相关推荐
fengci.1 分钟前
ctfshow(web入门)279-286
java·开发语言·学习
fy121633 分钟前
navicat15安装破解
java
ok_hahaha8 分钟前
java从头开始-苍穹外卖day05-Redis及店铺营业状态设置
java·开发语言·redis
加洛斯31 分钟前
JAVA知识梳理:一文搞懂集合中的List与ArrayList的基础与进阶
java·后端·面试
架构师沉默1 小时前
女孩去旅行,给男朋友带回了一个难解的 Bug
java·后端·架构
xu_ws1 小时前
Spring-ai项目-deepseek-6-哄哄模拟器
java·人工智能·spring
刘 大 望1 小时前
SpringAI Tool Calling(工具调用)
java·spring boot·spring·ai·maven·intellij-idea·文心一言
222you1 小时前
Java 并发编程(1)
java·开发语言
岁岁种桃花儿1 小时前
kubenetes从入门到上天系列第十九篇:Kubernetes安装Nginx ingress controller
java·nginx·kubernetes
做一个AK梦2 小时前
RedisForValueService.setIfAbsent()
java·分布式