quartz工程容器启动与 Service注入
容器启动
因为任务没有定义在 ApplicationContext.xml中,而是放到了数据库中,SpringBoot启动时,怎么读取任务信息?
或者,怎么在 Spring启动完成的时候做一些事情?
创建一个类,实现 CommandLineRunner接口,实现 run方法。
从表中查出状态是 1的任务,然后构建。
Service类注入到 Job中
Spring Bean如何注入到实现了Job接口的类中?
例如在 TestTask3中,需要注入 ISysJobService,查询数据库发送邮件。
如果没有任何配置,注入会报空指针异常。
原因:
因为定时任务 Job对象的实例化过程是在 Quartz中进行的,而 Service Bean是由Spring容器管理的,Quartz察觉不到
Service Bean的存在,所以无法将 Service Bean装配到 Job对象中。
分析:
Quartz集成到 Spring中,用到 SchedulerFactoryBean,其实现了 InitializingBean方法,在唯一的方法
afterPropertiesSet()在 Bean的属性初始化后调用。
调度器用 AdaptableJobFactory对 Job对象进行实例化。所以,如果我们可以把这个 JobFactory指定为我们自定义的工厂的话,就可以在
Job实例化完成之后,把 Job纳入到 Spring容器中管理。
解决这个问题的步骤:
1、定义一个 AdaptableJobFactory,实现 JobFactory接口,实现接口定义的newJob方法,在这里面返回 Job实例
2、定义一个 MyJobFactory,继承 AdaptableJobFactory。使用 Spring的 AutowireCapableBeanFactory,把 Job实例注入到容器中。
/**** 将Spring的对象注入到Quartz Job 2*/
@Component
public class MyJobFactory extends AdaptableJobFactory {@Autowiredprivate AutowireCapableBeanFactory capableBeanFactory;protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {//调用父类的方法Object jobInstance = super.createJobInstance(bundle);capableBeanFactory.autowireBean(jobInstance);return jobInstance;}
}
指定 Scheduler的 JobFactory为自定义的 JobFactory。
/*** 这个类用于启动SpringBoot时,加载作业。run方法会自动执行。** 另外可以使用 ApplicationRunner**/
@Component
public class InitStartSchedule implements CommandLineRunner {private final Logger logger = LoggerFactory.getLogger(this.getClass());@Autowiredprivate ISysJobService sysJobService;@Autowiredprivate MyJobFactory myJobFactory;@Overridepublic void run(String... args) throws Exception {/*** 用于程序启动时加载定时任务,并执行已启动的定时任务(只会执行一次,在程序启动完执行)*///查询job状态为启用的HashMap<String,String> map = new HashMap<String,String>();map.put("jobStatus", "1");List<SysJob> jobList= sysJobService.querySysJobList(map);if( null == jobList || jobList.size() ==0){logger.info("系统启动,没有需要执行的任务... ...");}// 通过SchedulerFactory获取一个调度器实例SchedulerFactory sf = new StdSchedulerFactory();Scheduler scheduler = sf.getScheduler();// 如果不设置JobFactory,Service注入到Job会报空指针scheduler.setJobFactory(myJobFactory);// 启动调度器scheduler.start();for (SysJob sysJob:jobList) {String jobClassName=sysJob.getJobName();String jobGroupName=sysJob.getJobGroup();//构建job信息JobDetail jobDetail = JobBuilder.newJob(getClass(sysJob.getJobClassPath()).getClass()).withIdentity(jobClassName, jobGroupName).build();if (StringUtils.isNotEmpty(sysJob.getJobDataMap())) {JSONObject jb = JSONObject.parseObject(sysJob.getJobDataMap());Map<String, Object> dataMap = (Map<String, Object>)jb.get("data");for (Map.Entry<String, Object> m:dataMap.entrySet()) {jobDetail.getJobDataMap().put(m.getKey(),m.getValue());}}//表达式调度构建器(即任务执行的时间)CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(sysJob.getJobCron());//按新的cronExpression表达式构建一个新的triggerCronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobClassName, jobGroupName).withSchedule(scheduleBuilder).startNow().build();// 任务不存在的时候才添加if( !scheduler.checkExists(jobDetail.getKey()) ){try {scheduler.scheduleJob(jobDetail, trigger);} catch (SchedulerException e) {logger.info("\n创建定时任务失败"+e);throw new Exception("创建定时任务失败");}}}}public static BaseJob getClass(String classname) throws Exception{Class<?> c= Class.forName(classname);return (BaseJob)c.newInstance();}
}
scheduler.setJobFactory(myJobFactory);
考虑这么一种情况:
正在运行的 Quartz节点挂了,而所有人完全不知情……
quartz工程容器启动与 Service注入相关推荐
- service注入为null_如何解决quartz调度时候,job中的service为null的问题?
在需要用到调度任务的时候,发现job中的通过依赖注入的service对象为null.如下: @Component public class ExpiredOrderJob implements Job ...
- 【quartz】quartz定时任务service注入失败
quartz定时任务service注入失败的详细的原因我查了查是这样的: Job是在quartz的框架中实例化的,service是在spring容器中创建出来的,所以Job实现类不受spring管理, ...
- 容器启动失败 ERROR: for log Cannot start service log: OCI runtime create failed: container_linux.go:346
完整错误信息: ERROR: for log Cannot start service log: OCI runtime create failed: container_linux.go:346: ...
- 【spring容器启动】之bean的实例化和初始化(文末附:spring循环依赖原理)
本次我们通过源码介绍ApplicationContext容器初始化流程,主要介绍容器内bean的实例化和初始化过程.ApplicationContext是Spring推出的先进Ioc容器,它继承了旧版 ...
- 阿里面试真题:Spring容器启动流程
有情怀,有干货,微信搜索[三太子敖丙]关注这个不一样的程序员. 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的系列文章. ...
- 【Spring】SpringIOC容器启动过程源码分析 以及 循环依赖问题
1.Spring是什么 Spring是一款轻量级的开发框架 . 简而言之 Spring提高了开发效率 两个核心 IOC 和 AOP 1.1 IOC ( Inversion of Control ) 是 ...
- SpringMVC源码分析_1 SpringMVC容器启动和加载原理
SpringMVC源码分析_1 SpringMVC启动和加载原理 ...
- spring源码阅读(3)-- 容器启动之BeanFactoryPostProcessor
接着上文<spring源码阅读(2)-- 容器启动之加载BeanDefinition>,当spring加载完所有BeanDefinition时,并不会马上去创建bean,而是先配置bean ...
- Dockerfile指令详解: CMD 容器启动命令
CMD 容器启动命令 CMD 指令的格式和 RUN 相似,也是两种格式: shell 格式:CMD <命令> exec 格式:CMD ["可执行文件", "参 ...
最新文章
- 收集一些好的技术文档
- 六、OpenStack配置计算结点
- BAT-使用BAT生成快捷方式
- 升级版记事本 Notepad++
- 部署文档撰写经验分享
- MyBatis入门基础(一)
- [转]Serverless,后端小程序的未来
- 7.2.5 dps 测试软件,《魔兽世界》7.2.5兽王猎DPS改动测试
- AHCI驱动下载与手动安装图解
- 京东大数据平台进化之路
- Python中常见的__init__.py是什么意思?详解Python import的方式和原理
- 官方纯净版windows10教育版安装密钥极其下载地址
- 名帖57 虞世南 小楷《演连珠》
- 教授专栏01 | 汪扬:元宇宙助香港,新经济创未来
- Ubuntu16.04安装QQ和微信(亲测有效)
- table(单击行,把当行的单选按钮(radio)设为选中状态,并应用当前样式)
- 吴恩达deeplearning之CNN—卷积神经网络入门
- SpringBoot整合rabbitmq使用案例
- 程序设计综合实验——集合的表示与实现
- 大数据是什么?发展前景怎么样