Spring Boot @Scheduled 执行两遍

使用spring cloud[Dalston.SR1]版本开发定时job时,发现job执行了两次;
下面日志里发现一个job被一个任务调度池(task-scheduler)里的两个worker(task-scheduler-1 和 task-scheduler-2)执行,很奇怪;

2018-02-23 14:28:30.001 [task-scheduler-2] INFO  c.k.micro.cfca.scheduled.ContractSealApplyJob - ==回调job==开始==
2018-02-23 14:28:30.002 [task-scheduler-2] INFO  c.k.micro.cfca.scheduled.ContractSealApplyJob - ==回调job==结束==
2018-02-23 14:28:30.003 [task-scheduler-1] INFO  c.k.micro.cfca.scheduled.ContractSealApplyJob - ==回调job==开始==
2018-02-23 14:28:30.003 [task-scheduler-1] INFO  c.k.micro.cfca.scheduled.ContractSealApplyJob - ==回调job==结束==

在构造方法里加入log,确认了类只被加载了一次;

示例代码:

@RefreshScope
@Component
@EnableScheduling
public class ContractSealApplyJob{

	@Value("${value1}")
	private String value1;

	/**
     * 进行回调job
     */
    @Scheduled(cron = "${0/30 * * * * *}")//每30秒
    public void doCallBack(){
		logger.info("==回调job==开始==");
		....
		logger.info("==回调job==结束==");
	}
}

发现是spring cloud config 里的注解@RefreshScope导致;正确用法是把配置项放到一个Config类里面;然后在Job里注入。 @RefreshScope注解的类,在运行时刷新后,会重新生成一个新的实例;不过在上述Job里并未被重新实例化(没有刷新),而是把Job放入池里两次。

/**
 * Convenience annotation to put a <code>@Bean</code> definition in
 * {@link org.springframework.cloud.context.scope.refresh.RefreshScope refresh scope}.
 * Beans annotated this way can be refreshed at runtime and any components that are using
 * them will get a new instance on the next method call, fully initialized and injected
 * with all dependencies.
 * 
 * @author Dave Syer
 *
 */
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Scope("refresh")
@Documented
public @interface RefreshScope {
	/**
	 * @see Scope#proxyMode()
	 */
	ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;

}

@RefreshScope还有别的坑,详见:http://www.cnblogs.com/yjmyzz/p/8085530.html

猜你喜欢

转载自my.oschina.net/placeholder/blog/1623070