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的问题?相关推荐
- antimalware service executable占用内存_解决 vue 项目运行过程中内存泄漏问题
vue-cli3.0 内存溢出 JavaScript heap out of memory vue-cli3.0构建的项目,开发过程中,可能会遇到内存溢出的情况,改动一点代码,代码编译,进程就会断掉, ...
- Angularjs1.x 中的 service,factory,provider,constant,value
了解 Angularjs1.x 中的 service,factory,provider,constant,value 的应用场景及区别 不管 service , factory 还是 provider ...
- quartz工程容器启动与 Service注入
容器启动 因为任务没有定义在 ApplicationContext.xml中,而是放到了数据库中,SpringBoot启动时,怎么读取任务信息? 或者,怎么在 Spring启动完成的时候做一些事情? ...
- 【quartz】quartz定时任务service注入失败
quartz定时任务service注入失败的详细的原因我查了查是这样的: Job是在quartz的框架中实例化的,service是在spring容器中创建出来的,所以Job实现类不受spring管理, ...
- 解决quartz的job无法注入spring对象
一般情况下,quartz的job中使用autowired注解注入的对象为空,这时候我们就要使用spring-quartz提供的AdaptableJobFactory类. 自定义一个类: [java] ...
- 解决.quartz.ObjectAlreadyExistsException: Unable to store Job : ‘jyGroup.jyJob‘, because one already
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 1. 报错如题: 定时任务出现异常 : org.quartz.ObjectAlreadyExists ...
- 【Spring】Service 注入失败,空指针
service层的类都有用@Service标识,但报空指针,注入失败,很可能是因为spring的application配置和springmvc的配置文件配置错误,导致容器冲突了. spring和spr ...
- Angular报注入错误,以及解决方式,$injector:unpr
1.页面错误如:$injector:unpr angular.min.js:80 Error: [$injector:unpr] http://errors.angularjs.org/1.2.9/$ ...
- 解决无法注入spring容器,获取不到spring容器中的bean问题
解决无法注入spring容器,获取不到spring容器中的bean问题 前两天工作中遇到一个问题,收到的需求是根据logbak日志实现通过过滤错误日志发送预警邮件到邮箱,logback自定义实现类如下 ...
最新文章
- OpenArkCompiler方舟编译
- PCL点云特征描述与提取(4)
- 怎么判断应用程序是多少位运行的
- Python time asctime()方法
- 工作篇-佛山三水恒大-2020.10.23
- php factory interface,PHP设计模式之工厂方法*解读
- MIFARE系列6《射频卡与读写器的通讯》
- git diff 常见用法
- 第2章[2.1] 开发模式及快速测试方式
- 两个点 定位_智造讲堂:RFID定位导航技术
- 微课在小学计算机教学中的应用,微课技术在小学信息技术课堂中的应用
- OpenGL 高质量纹理过滤的实例
- python中利用字典加密字符串_Python列表,字典和字符串操作
- java BigDecimal.ROUND_UP和BigDecimal.ROUND_DOWN的用处
- Vscode怎么进行文件对比-Vscode文件对比的方法介绍
- Dynamics 365 设置SMTP邮箱配置时凭据为灰色无法编辑的解决方法
- Flutter Demo 简单的涂鸦应用
- 决策树算法的理论和实践
- CMake是什么?有什么用?
- 关于IOS的学习(wxhl)曾海明