Java

发布于 更新于

AI总结: 本文介绍了在Spring框架中,使用@RefreshScope注解时,Bean的刷新机制导致@Scheduled注解的方法失效的问题。由于ScheduledAnnotationBeanPostProcessor只在容器初始化时执行一次,新创建的Bean中的@Scheduled方法不会被注册,从而导致定时任务无法正常运行。为了解决这个问题,提供了一种简单的解决方案,即实现ApplicationListener接口,监听RefreshScopeRefreshedEvent事件,以便在Bean刷新时重新注册定时任务。 优化建议: 1. 在onApplicationEvent方法中,添加逻辑以重新注册@Scheduled任务,确保任务在Bean刷新后能够正常执行。 2. 考虑使用其他机制,如使用Spring的TaskScheduler,来管理定时任务,以避免@Scheduled与@RefreshScope之间的冲突。 3. 在文档中提供更多的解决方案和链接,以便用户能找到其他可能的解决方案。

当@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

    }
}

相关链接

@RefreshScope stops @Scheduled task

@RefreshScope导致@Scheduled失效