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)

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

相关推荐
夜晚中的人海19 小时前
【C++】智能指针介绍
android·java·c++
正在走向自律20 小时前
RSA加密从原理到实践:Java后端与Vue前端全栈案例解析
java·前端·vue.js·密钥管理·rsa加密·密钥对·aes+rsa
咯哦哦哦哦20 小时前
关于QT 打印中文 乱码问题
java·数据库·qt
爱读源码的大都督20 小时前
天下苦@NonNull久矣,JSpecify总算来了,Spring 7率先支持!
java·后端·架构
木头没有瓜20 小时前
Slf4j 接口文档左侧菜单有显示,但是点击后空白
java
野犬寒鸦20 小时前
从零起步学习Redis || 第十二章:Redis Cluster集群如何解决Redis单机模式的性能瓶颈及高可用分布式部署方案详解
java·数据库·redis·后端·缓存
cxyxiaokui00121 小时前
还在用 @Autowired 字段注入?你可能正在写出“脆弱”的 Java 代码
java·后端·spring
珹洺21 小时前
Java-Spring入门指南(二十二)SSM整合前置基础
java·开发语言·spring
天天摸鱼的java工程师21 小时前
Java IO 流 + MinIO:游戏玩家自定义头像上传(格式校验、压缩处理、存储管理)
java·后端
程序员小富21 小时前
改了 Nacos 一行配置,搞崩线上支付系统!
java·后端