容器启动

因为任务没有定义在 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注入相关推荐

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

    在需要用到调度任务的时候,发现job中的通过依赖注入的service对象为null.如下: @Component public class ExpiredOrderJob implements Job ...

  2. 【quartz】quartz定时任务service注入失败

    quartz定时任务service注入失败的详细的原因我查了查是这样的: Job是在quartz的框架中实例化的,service是在spring容器中创建出来的,所以Job实现类不受spring管理, ...

  3. 容器启动失败 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: ...

  4. 【spring容器启动】之bean的实例化和初始化(文末附:spring循环依赖原理)

    本次我们通过源码介绍ApplicationContext容器初始化流程,主要介绍容器内bean的实例化和初始化过程.ApplicationContext是Spring推出的先进Ioc容器,它继承了旧版 ...

  5. 阿里面试真题:Spring容器启动流程

    有情怀,有干货,微信搜索[三太子敖丙]关注这个不一样的程序员. 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的系列文章. ...

  6. 【Spring】SpringIOC容器启动过程源码分析 以及 循环依赖问题

    1.Spring是什么 Spring是一款轻量级的开发框架 . 简而言之 Spring提高了开发效率 两个核心 IOC 和 AOP 1.1 IOC ( Inversion of Control ) 是 ...

  7. SpringMVC源码分析_1 SpringMVC容器启动和加载原理

                                                                    SpringMVC源码分析_1 SpringMVC启动和加载原理     ...

  8. spring源码阅读(3)-- 容器启动之BeanFactoryPostProcessor

    接着上文<spring源码阅读(2)-- 容器启动之加载BeanDefinition>,当spring加载完所有BeanDefinition时,并不会马上去创建bean,而是先配置bean ...

  9. Dockerfile指令详解: CMD 容器启动命令

    CMD 容器启动命令 CMD 指令的格式和 RUN 相似,也是两种格式: shell 格式:CMD <命令> exec 格式:CMD ["可执行文件", "参 ...

最新文章

  1. 收集一些好的技术文档
  2. 六、OpenStack配置计算结点
  3. BAT-使用BAT生成快捷方式
  4. 升级版记事本 Notepad++
  5. 部署文档撰写经验分享
  6. MyBatis入门基础(一)
  7. [转]Serverless,后端小程序的未来
  8. 7.2.5 dps 测试软件,《魔兽世界》7.2.5兽王猎DPS改动测试
  9. AHCI驱动下载与手动安装图解
  10. 京东大数据平台进化之路
  11. Python中常见的__init__.py是什么意思?详解Python import的方式和原理
  12. 官方纯净版windows10教育版安装密钥极其下载地址
  13. 名帖57 虞世南 小楷《演连珠》
  14. 教授专栏01 | 汪扬:元宇宙助香港,新经济创未来
  15. Ubuntu16.04安装QQ和微信(亲测有效)
  16. table(单击行,把当行的单选按钮(radio)设为选中状态,并应用当前样式)
  17. 吴恩达deeplearning之CNN—卷积神经网络入门
  18. SpringBoot整合rabbitmq使用案例
  19. 程序设计综合实验——集合的表示与实现
  20. 大数据是什么?发展前景怎么样

热门文章

  1. 关于使用spring admin和consul一起做监控需要注意的配置
  2. 大道至简读书笔记02
  3. 接受数据,table列表,外加判断
  4. [silverlight]WCF和Web Service(ASMX)的soap header传输方法
  5. JavaEE目标及企业应用和互联网应用区别
  6. grenndao 插入表数据报错
  7. Spring Boot 整合 Redis 实现缓存操作
  8. List, Set, Map是否继承自Collection接口?
  9. yield return关键字怎么使用?
  10. MySQL主从复制,读写分离配置