问题背景
今天在弄一个手工爬虫框架的时候,由于有个功能如下:
- 在列表界面点击抓取,进行手工抓取
- 后台根据application.yml设置的定时任务自动触发抓取任务
/**
* 广东省政府采购中心
*/
@PostMapping("/fetchCGZX")
@Scheduled(cron="${scheduler.fetch}")
public ReturnT fetchCGZX(boolean manual){
if(!manual&&!schedulerUtil.SchedulerEnable){
log.info("未启动定时任务");
return ReturnT.ERROR("未启动定时任务");
}else{
return tenderService.fetchCGZX();
}
}
报错分析
根据错误信息我们可以分析,定时任务是不能带参数的
,也就是参数栏必须为空,这是SpringBoot自带Scheduler比较鸡肋的地方吧,但是如果你确定了用他,就必须要遵守这个规则,尽量使用无参数设置。
nested exception is java.lang.IllegalStateException: Encountered invalid @Scheduled method ‘syncCGZX’:
Only no-arg methods may be annotated with @Scheduled
控制台输出
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tenderController' defined in file [D:\workspace\java\TenderFetchSystem\target\classes\com\softdev\system\controller\TenderController.class]: Initialization of bean failed; nested exception is java.lang.IllegalStateException: Encountered invalid @Scheduled method 'syncCGZX': Only no-arg methods may be annotated with @Scheduled
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:603) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:895) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.__refresh(AbstractApplicationContext.java:550) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.jrLockAndRefresh(AbstractApplicationContext.java:40002) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:41008) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) ~[spring-boot-2.2.7.RELEASE.jar:2.2.7.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) [spring-boot-2.2.7.RELEASE.jar:2.2.7.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.2.7.RELEASE.jar:2.2.7.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.2.7.RELEASE.jar:2.2.7.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.2.7.RELEASE.jar:2.2.7.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [spring-boot-2.2.7.RELEASE.jar:2.2.7.RELEASE]
at com.softdev.system.Application.main(Application.java:15) [classes/:na]
Caused by: java.lang.IllegalStateException: Encountered invalid @Scheduled method 'syncCGZX': Only no-arg methods may be annotated with @Scheduled
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.processScheduled(ScheduledAnnotationBeanPostProcessor.java:499) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.lambda$null$1(ScheduledAnnotationBeanPostProcessor.java:362) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at java.lang.Iterable.forEach(Iterable.java:75) ~[na:1.8.0_222]
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.lambda$postProcessAfterInitialization$2(ScheduledAnnotationBeanPostProcessor.java:362) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684) ~[na:1.8.0_222]
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.postProcessAfterInitialization(ScheduledAnnotationBeanPostProcessor.java:361) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:431) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:595) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
... 17 common frames omitted
Process finished with exit code 1
解决方案
- 换用其他定时任务
- 改造成两个方法,一个
手工触发
一个定时触发
/**
* 广东省政府采购中心
*/
@PostMapping("/fetchCGZX")
public ReturnT fetchCGZX(){
return tenderService.fetchCGZX();
}
/**
* 广东省政府采购中心
*/
@Scheduled(cron="${scheduler.fetch}")
public ReturnT fetchCGZX_job(){
//判断是否启用
if(!schedulerUtil.SchedulerEnable){
log.info("未启动定时任务");
return ReturnT.ERROR("未启动定时任务");
}else{
return tenderService.fetchCGZX();
}
}