如何通过spring 向quartz动态注入service或者,传入动态参数?
这里主要用到了org.springframework.scheduling.quartz.JobDetailBean这个类的setJobDataAsMap的这个方法!
具体的API如下:
setJobDataAsMap
public void setJobDataAsMap(Map jobDataAsMap)
Register objects in the JobDataMap via a given Map.
These objects will be available to this Job only, in contrast to objects in the SchedulerContext.
Note: When using persistent Jobs whose JobDetail will be kept in the database, do not put Spring-managed beans or an ApplicationContext reference into the JobDataMap but rather into the SchedulerContext.
Parameters:
jobDataAsMap - Map with String keys and any objects as values (for example Spring-managed beans)
需要注意的是红色的部分,由spring管理的Service无法通过这个方法进行注入,
spring管理的service 只能放到SchedulerContext里面。
好的,我们来举个例子。
- <bean name="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
- <property name="dataSource" ref="dataSource" />
- <property name="schedulerContextAsMap">
- <map>
- <!-- spring 管理的service需要放到这里,才能够注入成功 -->
- <description>schedulerContextAsMap</description>
- <entry key="webSiteService" value-ref="webSiteService"/>
- <entry key = "mappingService" value-ref="mappingService"/>
- <entry key="detailService" value-ref = "detailService"></entry>
- </map>
- </property>
- <property name="applicationContextSchedulerContextKey" value="applicationContextKey" />
- <property name="configLocation" value="classpath:quartz.properties" />
- </bean>
- <bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
- <property name="jobClass" value = "com.fangjia.dc.quartz.MyQuartzJob"/>
- <property name="jobDataAsMap">
- <map>
- <!-- 非spring管理的service放到这里,就可以注入进去 -->
- <description>jobDataAsMap</description>
- <!-- key 属性值,value 对应的bean -->
- <entry key="uploader" value-ref="uploader" />
- </map>
- </property>
- </bean>
<bean name="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="schedulerContextAsMap">
<map>
<!-- spring 管理的service需要放到这里,才能够注入成功 -->
<description>schedulerContextAsMap</description>
<entry key="webSiteService" value-ref="webSiteService"/>
<entry key = "mappingService" value-ref="mappingService"/>
<entry key="detailService" value-ref = "detailService"></entry>
</map>
</property>
<property name="applicationContextSchedulerContextKey" value="applicationContextKey" />
<property name="configLocation" value="classpath:quartz.properties" />
</bean>
<bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value = "com.fangjia.dc.quartz.MyQuartzJob"/>
<property name="jobDataAsMap">
<map>
<!-- 非spring管理的service放到这里,就可以注入进去 -->
<description>jobDataAsMap</description>
<!-- key 属性值,value 对应的bean -->
<entry key="uploader" value-ref="uploader" />
</map>
</property>
</bean>
这里一共注入了 bean,分别是webSiteService,mappingService,detailService和uploader,然后在MyQuartzJob中使用注入的service
- public class MyQuartzJob extends QuartzJobBean {
- private static final Logger logger = Logger.getLogger(MyQuartzJob.class);
- private Uploader uploader;
- private IService<WebSite> webSiteService;
- private IService<Mapping> mappingService;
- private IService<MappingDetail> detailService;
- @Override
- protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
- try {
- //获取JobExecutionContext中的service对象
- SchedulerContext skedCtx = context.getScheduler().getContext();
- //获取SchedulerContext中的service
- //这里的service就是通过配置文件 配置的
- webSiteService = (IService<WebSite>)skedCtx.get("webSiteService");
- mappingService = (IService<Mapping>)skedCtx.get("mappingService");
- detailService = (IService<MappingDetail>)skedCtx.get("detailService");
- //获取 当前的trigger 名称,
- Trigger trigger = context.getTrigger();
- String name = trigger.getName();
- //从trigger中的jobDataMap中获取uploader
- uploader = (Uploader) context.getJobDetail.getJobDataMap().get("uploader");
- WebSite webSite = webSiteService.findByName(name);
- logger.info("webSite id:" + webSite.getId());
- loadMappingConfiguration(webSite);
- uploader.process(webSite, typeXpathFiels, domainMap);
- } catch (SchedulerException e) {
- e.printStackTrace();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- //属性的 get set方法
- }
public class MyQuartzJob extends QuartzJobBean {
private static final Logger logger = Logger.getLogger(MyQuartzJob.class);
private Uploader uploader;
private IService<WebSite> webSiteService;
private IService<Mapping> mappingService;
private IService<MappingDetail> detailService;
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
try {
//获取JobExecutionContext中的service对象
SchedulerContext skedCtx = context.getScheduler().getContext();
//获取SchedulerContext中的service
//这里的service就是通过配置文件 配置的
webSiteService = (IService<WebSite>)skedCtx.get("webSiteService");
mappingService = (IService<Mapping>)skedCtx.get("mappingService");
detailService = (IService<MappingDetail>)skedCtx.get("detailService");
//获取 当前的trigger 名称,
Trigger trigger = context.getTrigger();
String name = trigger.getName();
//从trigger中的jobDataMap中获取uploader
uploader = (Uploader) context.getJobDetail.getJobDataMap().get("uploader");
WebSite webSite = webSiteService.findByName(name);
logger.info("webSite id:" + webSite.getId());
loadMappingConfiguration(webSite);
uploader.process(webSite, typeXpathFiels, domainMap);
} catch (SchedulerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
//属性的 get set方法
}
定时任务的动态管理,没有配置的spring文件中
采用页面传值,实现quartz定时任务的CRUD
- public void schedule(String name, CronExpression cronExpression,String group) throws SchedulerException {
- //添加Job 给scheduler,允许 replace
- jobDetail.setRequestsRecovery(true);
- //孤立线程 不再保存在DB中
- jobDetail.setDurability(false);
- jobDetail.setName(name);
- logger.info(" is durable:" + jobDetail.isDurable());
- //设置replace为true,相同名字的job存在,则替换
- scheduler.addJob(jobDetail, true);
- CronTrigger cronTrigger = new CronTrigger(name, group, jobDetail.getName(), Scheduler.DEFAULT_GROUP);
- cronTrigger.setCronExpression(cronExpression);
- scheduler.scheduleJob(cronTrigger);
- scheduler.rescheduleJob(cronTrigger.getName(), cronTrigger.getGroup(), cronTrigger);
- }
- public void pauseTrigger(String triggerName, String group) throws SchedulerException {
- logger.info("pause triggerName:" + triggerName);
- scheduler.pauseTrigger(triggerName, group);
- }
- public void resumeTrigger(String triggerName, String group) throws SchedulerException {
- logger.info("resume trigger:" + triggerName + " group:" + group);
- scheduler.resumeTrigger(triggerName, group);
- }
- public boolean removeTrigdger(String triggerName, String group) throws SchedulerException {
- scheduler.pauseTrigger(triggerName, group);
- return scheduler.unscheduleJob(triggerName, group);
- }
public void schedule(String name, CronExpression cronExpression,String group) throws SchedulerException {
//添加Job 给scheduler,允许 replace
jobDetail.setRequestsRecovery(true);
//孤立线程 不再保存在DB中
jobDetail.setDurability(false);
jobDetail.setName(name);
logger.info(" is durable:" + jobDetail.isDurable());
//设置replace为true,相同名字的job存在,则替换
scheduler.addJob(jobDetail, true);
CronTrigger cronTrigger = new CronTrigger(name, group, jobDetail.getName(), Scheduler.DEFAULT_GROUP);
cronTrigger.setCronExpression(cronExpression);
scheduler.scheduleJob(cronTrigger);
scheduler.rescheduleJob(cronTrigger.getName(), cronTrigger.getGroup(), cronTrigger);
}
public void pauseTrigger(String triggerName, String group) throws SchedulerException {
logger.info("pause triggerName:" + triggerName);
scheduler.pauseTrigger(triggerName, group);
}
public void resumeTrigger(String triggerName, String group) throws SchedulerException {
logger.info("resume trigger:" + triggerName + " group:" + group);
scheduler.resumeTrigger(triggerName, group);
}
public boolean removeTrigdger(String triggerName, String group) throws SchedulerException {
scheduler.pauseTrigger(triggerName, group);
return scheduler.unscheduleJob(triggerName, group);
}
quartz.properties设置
- org.quartz.scheduler.instanceName = DefaultQuartzScheduler
- org.quartz.scheduler.rmi.export = false
- org.quartz.scheduler.rmi.proxy = false
- org.quartz.scheduler.wrapJobExecutionInUserTransaction = false
- org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
- org.quartz.threadPool.threadCount = 10
- org.quartz.threadPool.threadPriority = 5
- org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
- org.quartz.jobStore.misfireThreshold = 60000
- #org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
- org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
- org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
- org.quartz.jobStore.tablePrefix = QRTZ_
- org.quartz.jobStore.isClustered = false
- org.quartz.jobStore.maxMisfiresToHandleAtATime=1
- #org.quartz.jobStore.txIsolationLevelReadCommitted = true