@Value静态注入值以及自定义注解动态注入值的区别

        近日在工作中修改applicition.yml配置文件时,使用到@HeraclesDynamicConfig自定义注解可以动态读取配置文件修改内容,不需要启动服务器。便想记录一下底层的实现原理。

1.区别

  1. @Value 注解

    • @Value 注解是 Spring 框架提供的用于从配置文件中读取值并注入到 Spring Bean 中的注解。它在应用启动时将配置文件中的值注入到对应的属性中,但一旦注入后,这些值通常被视为静态的,不会再动态更新。
    • 当配置文件(如 application.properties 或 application.yml)中的值发生变化时,Spring 不会自动感知这些变化并更新已经注入的 Bean 属性。因此,需要重新启动应用程序来使新的配置值生效。
  2. 自定义注解

    • 自定义注解的设计可能不同于 Spring 的 @Value 注解。它可能利用了额外的机制或后台服务,能够在运行时动态地读取配置文件的变化,并将新的配置值注入到应用程序中,而无需重新启动服务器。
    • 这种实现可以借助后台线程、定时任务或监听器等机制,实时地监测配置文件的变化,并通过反射或其他手段更新被自定义注解标注的字段或属性。

2.底层实现

 

1. 自定义注解定义

首先,定义一个自定义注解,比如 @HeraclesDynamicConfig,它可以被应用到类、方法或字段上,以标记需要动态更新的配置属性。

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.FIELD, ElementType.METHOD})

public @interface HeraclesDynamicConfig {

String value();

}

2. 配置监听器

使用 Spring Boot 或其他框架的监听器来监听配置文件的变化。Spring Boot 提供了 ApplicationListener 接口和 ApplicationEvent 类,可以用来监听特定事件,如 EnvironmentChangeEvent

1import org.springframework.context.ApplicationListener;
2import org.springframework.context.event.ContextRefreshedEvent;
3import org.springframework.core.env.ConfigurableEnvironment;
4
5public class ConfigChangeListener implements ApplicationListener<ContextRefreshedEvent> {
6
7    private final ConfigurableEnvironment environment;
8
9    public ConfigChangeListener(ConfigurableEnvironment environment) {
10        this.environment = environment;
11    }
12
13    @Override
14    public void onApplicationEvent(ContextRefreshedEvent event) {
15        // 在这里检查和更新配置
16        if (event.getApplicationContext().getParent() == null) {
17            // 检查 application.properties/yml 更新
18            reloadConfiguration();
19        }
20    }
21
22    private void reloadConfiguration() {
23        // 重新加载配置
24    }
25}

3. 实现动态配置更新

reloadConfiguration 方法中,你需要实现从配置文件中读取配置并更新应用程序状态的逻辑。这可能涉及到对 ConfigurableEnvironment 的使用,以及将新的配置值反射到你的应用程序中。

4. 注解处理器

创建一个后处理(PostProcessor)或切面(Aspect),它会在运行时检查带有 @HeraclesDynamicConfig 注解的元素,并根据最新的配置文件内容更新它们。

1import org.aspectj.lang.ProceedingJoinPoint;
2import org.aspectj.lang.annotation.Around;
3import org.aspectj.lang.annotation.Aspect;
4import org.springframework.beans.factory.annotation.Autowired;
5import org.springframework.stereotype.Component;
6
7@Aspect
8@Component
9public class HeraclesDynamicConfigAspect {
10
11    @Autowired
12    private ConfigChangeListener configChangeListener;
13
14    @Around("@annotation(HeraclesDynamicConfig)")
15    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
16        // 在调用方法之前检查配置是否已更新
17        configChangeListener.reloadConfiguration();
18        return joinPoint.proceed();
19    }
20}

5. 使用自定义注解

在你的代码中使用 @HeraclesDynamicConfig 注解来标记那些需要动态更新配置的字段或方法。

1@Service
2public class MyService {
3
4    @Value("${my.property}")
5    @HeraclesDynamicConfig("my.property")
6    private String myProperty;
7
8    // ...
9}

请注意,以上只是小编记录的底层实现原理,尚未实操,如有需要还请结合实际。但大致的实现方法就是如此了。欢迎大家留言更好用的框架。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值