发布于 更新于
AI总结: 本文介绍了@RefreshScope在Spring中触发Bean刷新时,导致原有Bean实例被销毁并创建新实例的情况。由于ScheduledAnnotationBeanPostProcessor只在容器初始化时执行一次,新创建的Bean中的@Scheduled方法未被注册,导致定时任务失效。提供了一种解决方案,使用ApplicationListener监听RefreshScopeRefreshedEvent以解决定时任务失效的问题。
优化建议:
1. 在AlertSchedulerCron类的onApplicationEvent方法中,添加逻辑以重新注册@Scheduled任务。
2. 考虑使用Spring的TaskScheduler来动态调度任务,避免@Scheduled注解的限制。
3. 增加异常处理机制,确保在任务执行中出现错误时能够进行日志记录或告警。
4. 提供详细的文档或注释,帮助其他开发者理解如何使用该解决方案及其背后的原理。
当@RefreshScope触发Bean刷新时,原有的Bean实例被销毁,新实例被创建。 但是,ScheduledAnnotationBeanPostProcessor只在容器初始化时执行一次,不会重新扫描新创建的Bean。因此,新Bean中的@Scheduled方法未被注册,导致定时任务失效。
这里仅记录最简单的一种解决方案, 其他方式见相关链接
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
@RefreshScope
public class AlertSchedulerCron implements ApplicationListener<RefreshScopeRefreshedEvent> {
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Value("${pollingtime}")
private String pollingtime;
/*
* @Value("${interval}") private String interval;
*/
@Scheduled(cron = "${pollingtime}")
//@Scheduled(fixedRateString = "${interval}" )
public void task() {
System.out.println(pollingtime);
System.out.println("Scheduler (cron expression) task with duration : " + sdf.format(new Date()));
}
@Override
public void onApplicationEvent(RefreshScopeRefreshedEvent event) {
// TODO Auto-generated method stub
}
}