https://so.csdn.net/so/search/s.do?q=quartz&t=blog&u=zixiao217
参考链接:https://blog.csdn.net/Goligory/article/details/81451814
xml 配置:
注册trigger
<bean id="qrtzExampletrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="name" value="qrtzExampletrigger" />
<property name="group" value="qrtzExampleGroup"></property>
<property name="jobDetail" ref="qrtzExampleJobTask" />
<property name="cronExpression">
<!-- 此处写cron表达式 0 * * * * ? -->
<value>......</value>
</property>
</bean>
注册task
<bean id="qrtzExampleJobTask" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass">
<value>com.star.demo.ProjectQuartzJobBean</value> <!-- 作业类,也可以使用此类的子类继承StatefulJob 来防止定时任务的并发 -->
</property>
<property name="jobDataAsMap">
<map>
<entry key="executeDate" value="" />
<!-- 配置了这里会调用jobClass类里的setTargetObject等方法 -->
<entry key="targetObject" value="qrtzExampleJob" />
<entry key="targetMethod" value="execute" />
</map>
</property>
<property name="name" value="qrtzExampleJob"></property>
<property name="group" value="qrtzExampleGroup"></property>
<!-- requestsRecovery属性为true,则当Quartz服务被中止后,再次启动任务时会尝试恢复执行之前未完成的所有任务 -->
<!-- <property name="requestsRecovery" value="true" /> -->
<!-- 标识job是持久的,删除所有触发器的时候不被删除 -->
<property name="durability" value="true" />
<!-- 没有以下配置会异常 -->
<!--<property name="volatility" value="false"></property> -->
</bean>
注册自定义job
<bean id="qrtzExampleJob" class="com.star.demo.quartz.qrtzExampleJob"></bean>
调度中心加入trigger
<!-- 调度中心 -->
<bean id="scheduler"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean"
lazy-init="false" autowire="no">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:quartz-config.properties" />
<property name="triggers">
<list>
<ref bean="qrtzExampleTrigger"/>
......
</list>
</property>
<property name="schedulerContextAsMap">
<map>
<!-- spring管理的service -->
<description>schedulerContextAsMap</description>
<entry key="csdOrderBackStateService" value-ref="csdOrderBackStateServiceImpl"></entry>
......
<!-- thread -->
<entry key="monthBillExcelExecutor" value-ref="monthBillExcelExecutor"/>
......
</map>
</property>
<property name="applicationContextSchedulerContextKey" value="applicationContext" />
<!-- 必选,QuartzScheduler 延时启动,应用启动完后 QuartzScheduler 再启动 -->
<property name="startupDelay" value="60" />
<!-- 可选,QuartzScheduler 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 -->
<property name="overwriteExistingJobs" value="true" />
</bean>
作业类实例:
import java.lang.reflect.Method;
import org.quartz.JobExecutionException;
import org.quartz.PersistJobDataAfterExecution;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import common.Logger;
/**
自定义的QuartzJobBean (作业类)
*/
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public class ProjectQuartzJobBean extends QuartzJobBean implements ApplicationContextAware{
protected final Logger logger = Logger.getLogger(getClass());
private String targetMethod;
private String targetObject;
private ApplicationContext context;
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
try {
logger.info("开始执行 :" + targetObject); // 每个节点都打印此日志,但只有一个节点会执行
Object targetObj = context.getBean(targetObject);
Method m = null;
try {
m = targetObj.getClass().getMethod(targetMethod, new Class[] {JobExecutionContext.class});
m.invoke(targetObj, new Object[] {context});
} catch (Exception e) {
logger.error(e);
}
} catch (Exception e) {
throw new JobExecutionException(e);
}
}
public void setApplicationContext(ApplicationContext applicationContext) {
this.context = applicationContext;
}
public void setTargetObject(String targetObject) {
this.targetObject = targetObject;
}
public void setTargetMethod(String targetMethod) {
this.targetMethod = targetMethod;
}
}
Bean需要实现某个功能,但该功能必须借助于Spring容器才能实现,此时就必须让该Bean先获取Spring容器,然后借助于Spring容器实现该功能。为了让Bean获取它所在的Spring容器,可以让该Bean实现ApplicationContextAware接口。
Spring容器会检测容器中的所有Bean,如果发现某个Bean实现了ApplicationContextAware接口,Spring容器会在创建该Bean之后,自动调用该Bean的setApplicationContextAware()方法,调用该方法时,会将容器本身作为参数传给该方法——该方法中的实现部分将Spring传入的参数(容器本身)赋给该类对象的applicationContext实例变量,因此接下来可以通过该applicationContext实例变量来访问容器本身。
例如:
在CacheUtil中通过spring容器创建CacheManager实例
public class CacheUtils {
private static CacheManager cacheManager = ((CacheManager) SpringContextHolder.getBean("cacheManager"));
}