SpringBoot踩坑记录:玩转@Value注解-自定义PropertySourcesPlaceHolderConfigurer

本文记录了在SpringBoot中遇到无法将配置项直接放入properties文件的情况时,如何自定义注解@CustomValue及BeanPostProcessor实现取值,以及扩展@Value的解析范围,通过自定义PropetySourcesPlaceHolderConfigurer加载自定义配置项。文中详细阐述了两种方案的实现步骤、注意事项,并提供了相关示例代码。
摘要由CSDN通过智能技术生成

想法

开发环境:SpringBoot + IDEA

比如说,我们在代码中,有一些环境相关的变量配置到了 properties 配置文件中,使用时用 @Value 注解获取。
现在由于某种奇葩原因,有部分配置项不能直接配在配置文件properties中,需要以其他方式获取。

我们有以下几种方式可以来实现,先讲方案,后续再讲下原理。

方案一 自定义Value注解

自定义一个用法类似 @Value 的注解,取值逻辑自定义(实际原理与 @Value 并不相同),步骤如下:

1. 自定义一个取值注解 @CustomValue

比如我这里例子,定义一个名称为 CustomValue 的注解,注解只支持传入一个值 value,类似 @Value, 传入"${xxx}" 格式时表示取 key 为 xxx 的配置项。

@Target({
   ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface CustomValue {
   
    String value();
}

2. 自定义 BeanPostProcessor 处理注解

BeanPostProcessor 会在SpringApplication启动过程尾声被逐个调用,我们可以自定义一个 BeanPostProcessor 并用 @Component 注解交给 Spring 框架管理。在这个处理类中我们检查每一个 Spring 创建的对象,判断其中如果有被 CustomValue 注解的字段,则进行解析赋值。

@Component
public class CustomValueBeanPostProcessor implements BeanPostProcessor {
   

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
   
        if(bean == null){
   
            return bean;
        }
        //过滤出自定义注解@CustomValue标记的字段
        Field[] declaredFields = bean.getClass().getDeclaredFields();
        for(Field declaredField : declaredFields){
   
            CustomValue annotation = declaredField.getAnnotation(CustomValue.class);
            if(annotation == null){
   
                continue;
            }
            ReflectionUtils.makeAccessible(declaredField);
            try{
   
                //自定义解析注解字段获得值
                String value = getValue(annotation);
                //将值注入到目标字段中
                declaredField.set(bean, value);
            } catch (Exception e){
   
                e.printStackTrace();;
            }
        }
        return bean;
    }

    /** 用自定义方式获取值 */
    private String getValue(CustomValue annotation) {
   
		return "";
    }
}

3. 应用自定义的注解并测试

在Service层应用自定义的注解注入变量:

@Service
public class TestServiceImpl implements TestService{
   
    //使用官方注解
    @Value("${qc.test.value}")
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值