spring + quartz简单实现,没datasource(java config)
1. 定义scheduler执行的job类,一定要继承QuartzJobBean
2. jobDetail,具体那个类执行job
3. jobTrigger,调度时间、时区、定义它要执行的job
4. SchedulerFactoryBean,所有的job统一配置在这里,也就是说可以有多个jobDetail和jobTrigger一一对应,全放在这里
package com.cherrypicks.hsbcpayme.cs.config; import java.util.TimeZone; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.scheduling.quartz.CronTriggerFactoryBean; import org.springframework.scheduling.quartz.JobDetailFactoryBean; import org.springframework.scheduling.quartz.SchedulerFactoryBean; import com.cherrypicks.hsbcpayme.cs.scheduler.AutowiringSpringBeanJobFactory; import com.cherrypicks.hsbcpayme.cs.scheduler.CheckCustomerEmailScheduler; @Configuration @EnableAutoConfiguration @ComponentScan(basePackages = {"com.cherrypicks.hsbcpayme.cs.scheduler"}) public class SchedulerConfig { @Value("${check.email.cron:}") private String checkCustomerEmailCron; @Autowired private DataSourceConfig dataSourceConfig; @Autowired private ResourceLoader resourceLoader; @Bean public AutowiringSpringBeanJobFactory jobFactory() { return new AutowiringSpringBeanJobFactory(); } @Bean public JobDetailFactoryBean checkCustomerEmailJob(){ final JobDetailFactoryBean factory = new JobDetailFactoryBean(); factory.setJobClass(CheckCustomerEmailScheduler.class); factory.setDurability(true); return factory; } @Bean public CronTriggerFactoryBean checkCustomerEmailTrigger(){ final CronTriggerFactoryBean stFactory = new CronTriggerFactoryBean(); stFactory.setJobDetail(checkCustomerEmailJob().getObject()); // stFactory.setStartDelay(300); stFactory.setCronExpression(checkCustomerEmailCron); stFactory.setTimeZone(TimeZone.getTimeZone("GMT+8:00")); return stFactory; } @Bean public SchedulerFactoryBean schedulerFactoryBean() { final SchedulerFactoryBean scheduler = new SchedulerFactoryBean(); final Resource resource = resourceLoader.getResource("classpath:quartz.properties"); scheduler.setConfigLocation(resource); scheduler.setDataSource(dataSourceConfig.quartzDataSource()); scheduler.setTransactionManager(dataSourceConfig.quartzTransactionManager()); // This name is persisted as SCHED_NAME in db. for local testing could change to unique name to avoid collision with dev server scheduler.setSchedulerName("csQuartzScheduler"); // Will update database cron triggers to what is in this jobs file on each deploy. Replaces all previous trigger and job data that was in the database. scheduler.setOverwriteExistingJobs(true); scheduler.setAutoStartup(true); scheduler.setJobFactory(jobFactory()); scheduler.setJobDetails(checkCustomerEmailJob().getObject()); scheduler.setTriggers(checkCustomerEmailTrigger().getObject()); return scheduler; } }job类的写法,其中AbstractBaseScheduler是对QuartzJobBean的包装,实际还是继承QuartzJobBean
package com.cherrypicks.hsbcpayme.cs.scheduler; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.cherrypicks.hsbcpayme.cs.controller.TicketController; import com.cherrypicks.hsbcpayme.dao.TicketDao; import com.cherrypicks.hsbcpayme.service.ReceiveEmailService; import com.cherrypicks.hsbcpayme.service.TicketService; @Component public class CheckCustomerEmailScheduler extends AbstractBaseScheduler { @Autowired private ReceiveEmailService receiveEmailService; @Autowired private TicketService ticketSerice; @Autowired private TicketController ticketController; @Autowired private TicketDao ticketDao; @Override protected void executeInternal(final JobExecutionContext ctx) throws JobExecutionException { receiveEmailService.readMail(); } }就这样,简单的scheduler就可以跑起来了,后面会加入datasource,让quartz真正实现分布式server下的同步执行scheduler。
如果改用xml配置
<bean id="expiryRedeemCodeDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass" value="com.cherrypicks.appsdollar.scheduler.ExpiryRedeemCodeAction" /> <property name="durability" value="true" /> </bean> <bean id="expiryRedeemCodeTrigger" class="com.cherrypicks.appsdollar.common.scheduler.PersistableCronTriggerFactoryBean"> <property name="jobDetail" ref="expiryRedeemCodeDetail" /> <property name="cronExpression"> <value>0 0 0 * * ?</value> </property> <property name="timeZone"> <value>GMT+08:00</value> </property> </bean> <bean id="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="configLocation" value="classpath:quartz.properties" /> <property name="dataSource" ref="quartzDataSource" /> <property name="transactionManager" ref="quartzTransactionManager" /> <!-- This name is persisted as SCHED_NAME in db. for local testing could change to unique name to avoid collision with dev server --> <property name="schedulerName" value="apiQuartzScheduler" /> <!-- Will update database cron triggers to what is in this jobs file on each deploy. Replaces all previous trigger and job data that was in the database. YMMV --> <property name="overwriteExistingJobs" value="true" /> <property name="autoStartup" value="true" /> <property name="applicationContextSchedulerContextKey" value="applicationContext" /> <property name="jobFactory"> <bean class="com.cherrypicks.appsdollar.common.scheduler.AutowiringSpringBeanJobFactory" /> </property> <!-- NOTE: Must add both the jobDetail and trigger to the scheduler! --> <property name="jobDetails"> <list> <ref bean="expiryRedeemCodeDetail" /> </list> </property> <property name="triggers"> <list> <ref bean="expiryRedeemCodeTrigger" /> </list> </property> </bean>