项目中用到job 记录一下学习过程以及遇到的坑
一. maven依赖问题
首先时jar包方面 导入quartz与spring maven依赖时居然碰到了jar包冲突问题 死在第一步… 看日志发现quartz需要依赖c3p0 于是到入c3p0依赖解决了环境冲突 如下:
<!-- c3p0 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>mchange-commons-java</artifactId>
<version>0.2.11</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!-- 定时任务 -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<!--spring部分依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.2.0.RELEASE</version>
</dependency>
二.具体代码
创建一个class类继承QuartzJobBean
public class TestJob extends QuartzJobBean{
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("定时任务执行:"+new DateTime().toString("YYYY-MM-dd HH:mm:ss"));
String str = jobExecutionContext.getMergedJobDataMap().get("descString").toString();
System.out.println("从JobDetailBean中拿到自定义属性值:"+str);
}
}
三.配置文件
<bean id= "testJobDetailBean"
//注意由于我用的Spring4 所以这里是JobDetailFactoryBean,老版本使用的JobDetailBean
class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="name" value="exampleJob" />
<property name="jobClass"
value="job.TestJob"/>
<!-- 可以封装各种数据到JobExecutionContext里 -->
<property name="jobDataAsMap">
<map>
<entry key="descString" value="测试跑批"/>
</map>
</property>
</bean >
<!--为job配置触发时间-->
<bean id="testTaskTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="testJobDetailBean" />
<property name="cronExpression" value="0/10 * * * * ?" />
</bean >
<!--将调度器加入调度工厂-->
<bean id= "testSchedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers" >
<list>
<ref bean="testTaskTrigger" />
</list>
</property>
</bean>
四:运行结果
启动服务器,job执行
五.quartz注入Service
Quartz初始化是自己的JobContext,不同于Spring的ApplicationContext,所以无法直接注入 我使用的方法是自定义一个实体类继承Spring的SpringBeanJobFactory类
重写createJobInstance 将这个类配置在job配置文件中
public class MyJobFactory extends SpringBeanJobFactory {
@Autowired
private AutowireCapableBeanFactory beanFactory;
@Override
/**
* 这里覆盖了super的createJobInstance方法,对其创建出来的类再进行autowire。
*/
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object jobInstance = super.createJobInstance(bundle);
beanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
job实体类作如下更改
public class TestJob extends QuartzJobBean{
@Autowired
private UserService userService;
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("定时任务执行:"+new DateTime().toString("YYYY-MM-dd HH:mm:ss"));
String str = jobExecutionContext.getMergedJobDataMap().get("descString").toString();
System.out.println("从JobDetailBean中拿到自定义属性值:"+str);
System.out.println("调用service方法:"+userService.getMessage("成功注入service"));
System.out.println("job结束");
}
}
修改后的配置文件
<bean id= "testJobDetailBean"
class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="name" value="exampleJob" />
<property name="jobClass"
value="job.TestJob"/>
<!-- 可以封装各种数据到JobExecutionContext里 -->
<property name="jobDataAsMap">
<map>
<entry key="descString" value="测试跑批"/>
</map>
</property>
</bean >
<!--为job配置触发时间-->
<bean id="testTaskTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="testJobDetailBean" />
<property name="cronExpression" value="0/10 * * * * ?" />
</bean >
<!--将调度器加入调度工厂-->
<bean id= "testSchedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers" >
<list>
<ref bean="testTaskTrigger" />
</list>
</property>
<!--自定义jobFactory 解决service无法注入问题-->
<property name="jobFactory">
<bean class="job.MyJobFactory" />
</property>
</bean>
只增加配置了一个名为jobFactory的property属性
六:修改后 运行结果: