动态修改注解属性
最近遇到一个需求,期望能够根据当前的环境动态的设置 @Scheduled 注解的 cron() 属性
奇奇怪怪的需求有很多,当然,对我们来说,必须迎难而上
一、怎么做?
- 需求详情
① 项目启动时,查询数据库配置的Cron表达式
② 将@Scheduled注解中的Cron表达式进行动态修改 - 实现步骤
① 项目启动后的初始化操作可以通过@PostConstruct去实现
② 在初始化方法中,通过反射获取定时任务方法的@Scheduled()注解属性,并修改 - 完整代码
@Slf4j
@Component
public class ExecutorAspect {
private boolean inactive;
/**
* 定时设置调度检查器的激活状态{@link #inactive}
*/
@Scheduled(cron = "0 0 0 ? * *")
public void executorCheck() {
// 默认激活调度任务检查器
this.inactive = false;
log.info(">>>调度发起检查已开启:{}", LocalDateTime.now());
}
/**
* 校正{@link #executorCheck()}的{@code @Scheduled#cron()}
*/
@PostConstruct
@SuppressWarnings("unchecked")
public void rectifyCron() {
// 反射获取定时任务方法
Method executorCheck = ReflectionUtils.findMethod(this.getClass(), "executorCheck");
ReflectionUtils.makeAccessible(executorCheck);
// 获取 @Scheduled() 注解
Scheduled scheduled = executorCheck.getAnnotation(Scheduled.class);
InvocationHandler invocationHandler = Proxy.getInvocationHandler(scheduled);
// 此处略去查询数据库 Cron 表达式的操作(每1分钟执行一次)
String cron = "0 0/1 * * * ?";
Field field;
try {
// 这一段是核心代码,动态修改注解的属性值
field = invocationHandler.getClass().getDeclaredField("memberValues");
ReflectionUtils.makeAccessible(field);
Map<String, Object> memberValues = (Map<String, Object>) field.get(invocationHandler);
memberValues.put("cron", cron);
log.info(">>>更新调度检查的Cron表达式为:{}", cron);
} catch (ReflectiveOperationException e) {
throw new BatchException("更新定时任务corn表达式错误:" + e.getMessage());
}
}
}
本文介绍了一个在项目启动时根据数据库配置动态调整@Scheduled注解cron表达式的需求。通过@PostConstruct和反射技术,实现了定时任务Cron表达式的动态更新,确保任务按新的配置执行。
2370

被折叠的 条评论
为什么被折叠?



