When using spring cloud[Dalston.SR1] version to develop timing job, it is found that the job has been executed twice;
In the following log, it is found that a job is executed by two workers (task-scheduler-1 and task-scheduler-2) in a task scheduler pool, which is strange;
2018-02-23 14:28:30.001 [task-scheduler-2] INFO c.k.micro.cfca.scheduled.ContractSealApplyJob - ==Callback job==start== 2018-02-23 14:28:30.002 [task-scheduler-2] INFO c.k.micro.cfca.scheduled.ContractSealApplyJob - ==Callback job==End== 2018-02-23 14:28:30.003 [task-scheduler-1] INFO c.k.micro.cfca.scheduled.ContractSealApplyJob - ==Callback job==start== 2018-02-23 14:28:30.003 [task-scheduler-1] INFO c.k.micro.cfca.scheduled.ContractSealApplyJob - ==Callback job==End==
log is added to the constructor to confirm that the class is loaded only once;
Example code:
@RefreshScope @Component @EnableScheduling public class ContractSealApplyJob{ @Value("${value1}") private String value1; /** * Make callback job */ @Scheduled(cron = "${0/30 * * * * *}")//Every 30 seconds public void doCallBack(){ logger.info("==Callback job==start=="); .... logger.info("==Callback job==End=="); } }
It is found that the @ RefreshScope annotation in spring cloud config causes it; the correct usage is to put the configuration item into a Config class; then inject it into the Job. @The class annotated by RefreshScope will regenerate a new instance after refreshing at runtime; however, the above Job is not re instantiated (not refreshed), but put the Job into the pool twice.
/** * 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; }
@There are other pits for RefreshScope, see http://www.cnblogs.com/yjmyzz/p/8085530.html for details