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)

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

相关推荐
哭哭啼7 小时前
JAVA服务问题诊断
java·开发语言·jvm
evans在进步7 小时前
Spring Boot 核心机制详解:可执行 JAR、CORS、静态资源与配置绑定
spring boot·后端·jar
Sayuanni%37 小时前
SpringBoot 从注解到源码:核心知识点总结
java·spring boot·后端
坚定信念,勇往无前8 小时前
Maven 私有仓库-nexus
java
Minner-Scrapy8 小时前
Scrapy 2.17 源码解析:Scheduler 调度器与磁盘/内存双队列
java·爬虫·python·scrapy·网络爬虫·twisted
晚风醉蝶8 小时前
1-11-奇偶排序-OddEvenSort
java·数据结构·算法
夏天拐跑了西瓜8 小时前
Spring Cloud 微服务实战(三):一个服务挂了,凭什么拖垮整个系统?Sentinel 限流熔断实战
java·spring cloud·微服务
2601_967264289 小时前
Jetpack Compose 实践指南:从入门到进阶
java·学习
m0_587383009 小时前
社区家政系统开发实战:从需求分析到上线部署全指南
java·spring boot·spring·需求分析
凤山老林9 小时前
动态 i18n 体系落地:Spring Boot 多租户热加载与前后端协同实践
java·spring boot·后端·i18n