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)

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

相关推荐
喜欢打篮球的普通人2 分钟前
rust模式和匹配
java·算法·rust
java小吕布15 分钟前
Java中的排序算法:探索与比较
java·后端·算法·排序算法
慢生活的人。21 分钟前
SpringSecurity+jwt+captcha登录认证授权总结
java·认证·rbac·权限·验证
2401_8576009540 分钟前
深入剖析:Spring MVC与Struts的较量
struts·spring·mvc
被猫枕的咸鱼41 分钟前
springmvc通过使用map来进行数据的接收和使用
spring
向阳12181 小时前
LeetCode40:组合总和II
java·算法·leetcode
云空1 小时前
《InsCode AI IDE:编程新时代的引领者》
java·javascript·c++·ide·人工智能·python·php
慧都小妮子1 小时前
Spire.PDF for .NET【页面设置】演示:复制 PDF 文档中的页面
java·pdf·.net
Dr_eamboat1 小时前
【Java】枚举类映射
java·开发语言·python
李少兄1 小时前
解决 Spring Boot 中 `Ambiguous mapping. Cannot map ‘xxxController‘ method` 错误
java·spring boot·后端