为什么有这种需求?
- 每次增加定时任务都要修改配置文件;
- 有些定时任务不一定是必须的,可以由运维人员去添加删除或者修改执行时间什么的,不可能每次都去改程序
程序环境:
Spring 3.1.2 、Quartz 1.8.6 其他版本没有试过不过应该差别不大;
步骤:
总共4个操作:
1.1. 新建一个任务类,也就是具体干活的类;
1.2.一个JobDetail类(保存任务类);
1.3.一个Trigger类(保存JobDetail和一些执行细节);
1.4.注册Trigger;
其中涉及到在Spring中动态增加Bean的知识,有兴趣的可以查询相关资料;
/**
*任务类
**/
public class TestDemon {
private static final Logger logger = LoggerFactory.getLogger(TestDemon.class);
public void startWork() {
logger.info("*********** working ***********");
}
}
@Controller
public class TimerDemo {
@Autowired
private SchedulerFactoryBean schedulerFactoryBean;
@RequestMapping(value = "/addTimer", method = {
RequestMethod.POST, RequestMethod.GET}
)
@ResponseBody
public void addTimer() throws SchedulerException {
Scheduler scheduler = schedulerFactoryBean.getScheduler();
/*将TestDemo注册到Spring*/
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(TestDemon.class);
WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
DefaultListableBeanFactory autowireCapableBeanFactory = (DefaultListableBeanFactory) wac.getAutowireCapableBeanFactory();
autowireCapableBeanFactory.registerBeanDefinition("testDemo",beanDefinitionBuilder.getBeanDefinition());
/* 将JobDetail注册到Spring */
beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(BeanInvokingJobDetailFactoryBean.class);
beanDefinitionBuilder.addPropertyValue("targetBean", "testDemo");
beanDefinitionBuilder.addPropertyValue("targetMethod", "startWork");
autowireCapableBeanFactory.registerBeanDefinition("testBeanInvokeJobDetail", beanDefinitionBuilder.getBeanDefinition());
/* 将Trigger注册到Spring */
beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(CronTriggerBean.class);
beanDefinitionBuilder.addPropertyValue("cronExpression","0/10 * * * * ?");
beanDefinitionBuilder.addPropertyValue("name", "test");
beanDefinitionBuilder.addPropertyValue("group", "DEFAULT");
beanDefinitionBuilder.addPropertyReference("jobDetail", "testBeanInvokeJobDetail");
autowireCapableBeanFactory.registerBeanDefinition("testDemonTrigger", beanDefinitionBuilder.getBeanDefinition());
/* 增加任务 */
scheduler.scheduleJob((JobDetail) ContextLoader.getCurrentWebApplicationContext().getBean("testBeanInvokeJobDetail"),
(Trigger) ContextLoader.getCurrentWebApplicationContext().getBean("testDemonTrigger"));
}
}