解决service无法注入
原因是job的实现类是在quartz中实例化出来的,不受spring的管理。所以就导致注入不进去了
1. 创建job工厂类
@Component
public class JobFactory extends AdaptableJobFactory {
/**
* AutowireCapableBeanFactory接口是BeanFactory的子类
* 可以连接和填充那些生命周期不被Spring管理的已存在的bean实例
*/
private AutowireCapableBeanFactory factory;
public JobFactory(AutowireCapableBeanFactory factory) {
this.factory = factory;
}
/**
* 创建Job实例
*/
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
// 实例化对象
Object job = super.createJobInstance(bundle);
// 进行注入(Spring管理该Bean)
factory.autowireBean(job);
//返回对象
return job;
}
}
2. 创建quartz配置文件
@Configuration
public class QuartzConfig {
private JobFactory jobFactory;
public QuartzConfig(JobFactory jobFactory){
this.jobFactory = jobFactory;
}
/**
* 配置SchedulerFactoryBean
*
* 将一个方法产生为Bean并交给Spring容器管理
*/
@Bean
public SchedulerFactoryBean schedulerFactoryBean() {
// Spring提供SchedulerFactoryBean为Scheduler提供配置信息,并被Spring容器管理其生命周期
SchedulerFactoryBean factory = new SchedulerFactoryBean();
// 设置自定义Job Factory,用于Spring管理Job bean
factory.setJobFactory(jobFactory);
return factory;
}
@Bean(name = "scheduler")
public Scheduler scheduler() {
return schedulerFactoryBean().getScheduler();
}
}
3. 操作job的工具类
@Service
public class QuartzManager {
@Autowired
private Scheduler scheduler;
@Autowired
private NewsJobService jobService;
/**
* 添加一个定时任务
*/
public void addJob(NewsJobEntity jobEntity) {
try {
if (isExists(jobEntity.getJobname(),jobEntity.getGroupname())){
throw new Exception("已存在该任务");
}
// 通过JobBuilder构建JobDetail实例
// JobDetail规定只能是实现Job接口的实例
//
JobDetail jobDetail = JobBuilder.newJob(CancelTop.class).withIdentity(jobEntity.getJobname(), jobEntity.getGroupname()).build();
jobDetail.getJobDataMap().put("jobid",jobEntity.getId());
// 基于表达式构建触发器
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity(jobEntity.getJobname(), jobEntity.getGroupname()) // 触发器名称和组
.startNow() // 马上启动触发器
.withSchedule(CronScheduleBuilder
.cronSchedule(CronUtil.getCron(jobEntity.getStartdate()))) // 将开始时间转为cron表达式
.build();
// 调度容器设置JobDetail和Trigger
scheduler.scheduleJob(jobDetail, trigger);
// 启动
if (!scheduler.isShutdown()) {
scheduler.start();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 修改一个任务的触发时间
* 重新让他执行
*/
public void updateJobTime(Long jobId, Date newStartDate) throws SchedulerException {
System.out.println(getJobs());
NewsJobEntity jobEntity = jobService.getById(jobId);
if (jobEntity == null){
return;
}
jobEntity.setStartdate(newStartDate);
jobEntity.setStatus(1);
try {
if (isExists(jobEntity.getJobname(),jobEntity.getGroupname())){
// 删除
removeJob(jobEntity.getJobname(),jobEntity.getGroupname());
if (isExists(jobEntity.getJobname(),jobEntity.getGroupname())){
throw new Exception("删除失败");
}
}
// 重新添加
addJob(jobEntity);
if (isExists(jobEntity.getJobname(),jobEntity.getGroupname())){
throw new Exception("删除失败");
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 移除一个任务
*/
public void removeJob(String jobname,String groupname) {
if (!isExists(jobname,jobname)){
return;
}
try {
TriggerKey triggerKey = TriggerKey.triggerKey(jobname, groupname);
// 停止触发器
scheduler.pauseTrigger(triggerKey);
// 移除触发器
scheduler.unscheduleJob(triggerKey);
// 删除任务
scheduler.deleteJob(JobKey.jobKey(jobname, groupname));
if (isExists(jobname,jobname)){
throw new Exception("删除失败");
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 获取任务是否存在
*/
public Boolean isExists(String triggerName, String triggerGroupName) {
try {
return !(scheduler.getTriggerState(TriggerKey.triggerKey(triggerName, triggerGroupName)) == Trigger.TriggerState.NONE);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 获取所有任务
*/
public Set<JobKey> getJobs() throws SchedulerException {
return scheduler.getJobKeys(GroupMatcher.anyGroup());
}
}
4. job类
@Component
@Slf4j
public class CancelTop implements Job {
@Autowired
NewsJobService newsJobService;
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
Long jobid = context.getJobDetail().getJobDataMap().getLong("jobid");;
NewsJobEntity jobEntity = newsJobService.getById(jobid);
/**
* 业务逻辑
*/
log.debug("任务执行成功,执行线程为" + Thread.currentThread().getName());
}
}