問題背景
今天在弄一個手工爬蟲框架的時候,由於有個功能如下:
- 在列表界面點擊抓取,進行手工抓取
- 後臺根據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();
}
}