日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

service注入为null_如何解决quartz调度时候,job中的service为null的问题?

發布時間:2024/9/27 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 service注入为null_如何解决quartz调度时候,job中的service为null的问题? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在需要用到調度任務的時候,發現job中的通過依賴注入的service對象為null.如下:

@Component public class ExpiredOrderJob implements Job {@Autowiredprivate EmployeeService employeeService; //這里的service對象為null@Overridepublic void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {……} }

問題的原因:

出現這個問題的根本原因,還得從spring的IOC和AOP的基本原理開始講起。

在IOC中,是spring先把需要放置到IOC容器的對象放入,然后在通過IOC機制去請求獲得該對象的時候,然后調用出來IOC容器中準備好的對象。具體在springboot中的表現,如果你在一個類中增加了Component的注解,或者在一個Configure中增加了Bean的注解,IOC就會明白你想要把該對象放入到容器,然后在需要容器幫你實例化的地方加入Autoware,容器就會把該對象給注入。需要注意的地方是,容器只能對容器注入的對象內部的屬性注入,如果你通過自己的代碼new了一個對象,這對象里面的Autoware的屬性是不起作用的。很好理解,因為你的對象不在容器的管理范圍,容器就無法去注入。

而在quartz的job對象,是通過直接傳入job類的class,由quartz框架去實例化的,而非通過spring框架去實例化的,自然就無法完成注解。

JobDetail jobDetail = JobBuilder.newJob(ExpiredOrderJob.class) //把job.class傳入了jobBuilder.withIdentity("expireOrder","group1").build();

解決的思路:

在job中通過Autoware注解去實現,是不太可能了。而JobDetail 可以通過jobDataMap的屬性來傳遞對象,我們可以在需要spring注入的地方,把我們要注入的對象放到jobDataMap中去,然后在job中取出來使用,來繞道完成注解。

版本1:

//在調用調度器的地方去實現注入 @Autowired private EmployeeService employeeService; private void scheduleSumJob(Scheduler scheduler) throws SchedulerException{JobDetail jobDetail = JobBuilder.newJob(SumJob.class).withIdentity("sumJob","group1").build();jobDetail.getJobDataMap().put("service",employeeService);CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/2 * * * * ?");CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("trigger1","group1").withSchedule(scheduleBuilder).build();scheduler.scheduleJob(jobDetail,cronTrigger);} //在job中去實現調用 public class SumJob implements Job {@Overridepublic void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException{EmployeeService employeeService = (EmployeeService)jobExecutionContext.getJobDetail().getJobDataMap().get("service");employeeService.freshAreaEmployeeNum();} }

經過測試,我們已經能解決了在job中無法注入的問題。但是也有一些缺點,比如我們要再數據庫中保存很多的任務,而每個任務所調用service都不一樣。我們就無法在我們的使用調度器的地方去實現找到需要注入的對象,然后放到jobDataMap中去。我們得一個更加通用的辦法:比如我們把spring的容器的context注入,然后job中需要什么注入對象,就直接從context中去獲得 ,這樣就實現了通用性:

版本2:

@Autowired private ServletContext servletContext; private void scheduleSumJob(Scheduler scheduler) throws SchedulerException{JobDetail jobDetail = JobBuilder.newJob(SumJob.class).withIdentity("sumJob","group1").build();jobDetail.getJobDataMap().put("context",servletContext);CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/2 * * * * ?");CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("trigger1","group1").withSchedule(scheduleBuilder).build();scheduler.scheduleJob(jobDetail,cronTrigger);}

job中對應的變化

public class SumJob implements Job {@Overridepublic void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException{ServletContext context = (ServletContext)jobExecutionContext.getJobDetail().getJobDataMap().get("context");WebApplicationContext cxt = (WebApplicationContext) context.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);EmployeeService employeeService = cxt.getBean(EmployeeService.class);employeeService.freshAreaEmployeeNum();} }

這樣做的好處就是把service的注入的獲得延遲了,可以在job中更加靈活的調用所需要的對象,而無需在啟用調度器的地方去思考,更加通用,降低了耦合。

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的service注入为null_如何解决quartz调度时候,job中的service为null的问题?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。