Java 如何使用quartz调度程序动态配置spring作业
我不熟悉Spring批处理框架和quartz调度器。我的任务是使用quartz scheduler动态调度一个新的Spring批处理作业。所有新的spring批处理作业的条目都使用触发器表达式保存在我的数据库中。问题是,对于来自数据库的每个新的spring批处理作业,我们都需要将其包装到quartz的调度程序作业中。所以,这意味着将有尽可能多的spring批处理作业,所以应该有许多批处理作业类来包装它们并由quartz调度器运行 quartz将所有作业和触发器条目存储到自己的数据库表中。我在配置文件中配置了它。此作业将始终是quartz的作业,而不是spring批处理作业。 这是我的主要方法,我将在这里编写数据库连接代码,找出新的springbatch作业名称和触发器表达式,并将它们与quartz schedular绑定Java 如何使用quartz调度程序动态配置spring作业,java,spring,spring-mvc,spring-batch,quartz-scheduler,Java,Spring,Spring Mvc,Spring Batch,Quartz Scheduler,我不熟悉Spring批处理框架和quartz调度器。我的任务是使用quartz scheduler动态调度一个新的Spring批处理作业。所有新的spring批处理作业的条目都使用触发器表达式保存在我的数据库中。问题是,对于来自数据库的每个新的spring批处理作业,我们都需要将其包装到quartz的调度程序作业中。所以,这意味着将有尽可能多的spring批处理作业,所以应该有许多批处理作业类来包装它们并由quartz调度器运行 quartz将所有作业和触发器条目存储到自己的数据库表中。我在配置
public static void main(String[] args) {
try {
ApplicationContext context = new ClassPathXmlApplicationContext("quartz-context.xml");
JobLauncher launcher=(JobLauncher) context.getBean("jobLauncher");
JobLocator locator= (JobLocator) context.getBean("jobRegistry");
Scheduler schedulerFactoryBean=(Scheduler) context.getBean("quartzSchedulerFactoryBean");
JobDetail job = newJob(SpringBatchJob.class).withIdentity("myJob001", "group1").build();
Trigger trigger1 =newTrigger().withIdentity("myTrigger001", "group1").startNow().withSchedule(simpleSchedule().withIntervalInSeconds(10).repeatForever()).build();
schedulerFactoryBean.scheduleJob(job, trigger1);
schedulerFactoryBean.start();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
这里我们可以看到jobDetail,它是quartz作业,其执行方法用于运行spring批处理作业
springBatchjob.java
public class SpringBatchJob implements Job {
private String jobName;
private String batchJob;
private JobLocator jobLocator;
private JobLauncher jobLauncher;
private File contentDirectory;
private String directoryPath = "inputFiles";
public void init(){
contentDirectory = new File(directoryPath);
}
boolean fileFound = false;
public void performJob(String str) {}
public String getJobName() {
return jobName;
}
public void setBatchJob(String batchJob) {
this.batchJob = batchJob;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
public void setJobLocator(JobLocator jobLocator) {
this.jobLocator = jobLocator;
}
public void setJobLauncher(JobLauncher jobLauncher) {
this.jobLauncher = jobLauncher;
}
@Override
public void execute(JobExecutionContext arg0) throws org.quartz.JobExecutionException {
JobParameter jb= new JobParameter(5L);
Map<String, JobParameter> map= new HashMap<>();
map.put(jobName,jb);
ApplicationContext context = new ClassPathXmlApplicationContext("quartz-context.xml");
JobLauncher launcher=(JobLauncher) context.getBean("jobLauncher");
JobLocator locator= (JobLocator) context.getBean("jobRegistry");
setJobLauncher(launcher);
setJobLocator(locator);
setJobName("helloWorldJob");
// TODO Auto-generated method stub
JobExecution result = null;
try {
result = jobLauncher.run(jobLocator.getJob(jobName), new JobParameters(map));
} catch (JobExecutionAlreadyRunningException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JobRestartException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JobInstanceAlreadyCompleteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JobParametersInvalidException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchJobException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("ExamResult Job completetion details : "+result.toString());
}
公共类SpringBatchJob实现作业{
私有字符串jobName;
私有字符串批处理作业;
专用作业定位器作业定位器;
私有JobLauncher JobLauncher;
私有文件目录;
私有字符串directoryPath=“inputFiles”;
公共void init(){
contentDirectory=新文件(directoryPath);
}
布尔fileFound=false;
public void performJob(String str){}
公共字符串getJobName(){
返回作业名;
}
public void setBatchJob(字符串batchJob){
this.batchJob=batchJob;
}
public void setJobName(字符串jobName){
this.jobName=jobName;
}
public void setJobLocator(JobLocator JobLocator){
this.jobLocator=作业定位器;
}
public void setJobLauncher(JobLauncher JobLauncher){
this.jobLauncher=jobLauncher;
}
@凌驾
public void execute(JobExecutionContext arg0)抛出org.quartz.JobExecutionException{
JobParameter jb=新的JobParameter(5L);
Map Map=newhashmap();
地图放置(作业名称,jb);
ApplicationContext context=new ClassPathXmlApplicationContext(“quartz context.xml”);
JobLauncher launcher=(JobLauncher)context.getBean(“JobLauncher”);
JobLocator定位器=(JobLocator)context.getBean(“jobRegistry”);
setJobLauncher(启动器);
setJobLocator(定位器);
setJobName(“helloWorldJob”);
//TODO自动生成的方法存根
作业执行结果=null;
试一试{
结果=jobLauncher.run(jobLocator.getJob(jobName),new JobParameters(map));
}捕获(JobExecutionalReadyRunning异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}捕获(JobRestartException e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}捕获(JobInstancealReadyComplete异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}catch(作业参数sinvalidexception e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}捕获(无此异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
System.out.println(“ExamResult作业完成详细信息:+result.toString());
}
在setJobName
方法中,我正在硬编码我的spring批处理作业名称,
但在我的项目中,我们有将近800个工作,所以根据approarch,我们需要制作800个包装类
请帮助我,如何通过创建泛型类来解决此问题。我真诚地希望您不是真的在使用该类,它最终会在您反复创建应用程序时消耗您所有的内存 Spring已经支持quartz,特别是以
SpringBeanJobFactory
的形式构建作业,您可以利用它发挥自己的优势,特别是如果您使用一些自动布线功能扩展它
public class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
private ApplicationContext context;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object object = super.createJobInstance(bundle);
context.getAutowireCapableBeanFactory().autowireBean(object);
return object;
}
public void setApplicationContext(ApplicationContext applicationContext) {
this.context=applicationContext;
}
}
然后像这样重写你的职业课
public class SpringBatchJob implements Job {
private final Logger logger = LoggerFactory.getLogger(SpringBatchJob.class);
private String jobName;
@Autowired
private JobLocator jobLocator;
@Autowired
private JobLauncher jobLauncher;
@Override
public void execute(JobExecutionContext context) throws org.quartz.JobExecutionException {
JobDataMap JobDataMap = context.getMergedJobDataMap();
JobParametersBuilder builder = new JobParametersBuilder();
for (Map.Entry<String, Object) param : jobDataMap.entrySet()) {
String key = param.getKey();
Object val = param.getValue();
builder.addString(key, String.valueOf(val)); // Or make it smarter by doing type detection.
}
Job jobToLaunch = jobLocator.getJob(jobName);
JobExecution result;
try {
result = jobLauncher.run(jobToLaunch, builder.to);
} catch (JobExecutionException e) {
throw new org.quartz.JobExecutionException("Exception execution job '"+this.jobName+"'", e);
} finally {
logger.info("{} Job completetion details ", this.jobName, result);
}
}
}
注意.usingJobData(“jobName”,“helloWorldJob”)
,SpringBeanJobFactory
将尝试满足SpringBatchJob
类上的所有setter方法。它有一个setJobName
,启动时将注入helloWorldJob
。该功能由自动布线SpringBeanJobFactory
扩展,以自动连接所需的infra从Spring批处理中构造bean
如果需要向Spring批处理作业传递其他属性(如要使用的键或其他信息,只需使用JobData(“您的属性”,即您的值)添加另一个)
。在启动作业之前,修改后的SpringBatchJob
将所有quarts作业参数映射到Spring批处理参数
注意:这是从我的头顶输入的,我还没有实际测试过,但它至少可以让你知道如何做
public static void main(String[] args) {
try {
ApplicationContext context = new ClassPathXmlApplicationContext("quartz-context.xml");
JobLauncher launcher=(JobLauncher) context.getBean("jobLauncher");
JobLocator locator= (JobLocator) context.getBean("jobRegistry");
Scheduler schedulerFactoryBean=(Scheduler) context.getBean("quartzSchedulerFactoryBean");
JobDetail job = newJob(SpringBatchJob.class)
.withIdentity("myJob001", "group1")
.usingJobData("jobName", "helloWorldJob")
.build();
Trigger trigger1 =newTrigger().withIdentity("myTrigger001", "group1")
.startNow()
.withSchedule(simpleSchedule().withIntervalInSeconds(10).repeatForever())
.build();
schedulerFactoryBean.scheduleJob(job, trigger1);
schedulerFactoryBean.start();
} catch (SchedulerException e) {
e.printStackTrace();
}
}