gpt4 book ai didi

java - 如何使用 quartz 调度程序动态配置 spring 作业

转载 作者:行者123 更新时间:2023-11-30 06:09:11 32 4
gpt4 key购买 nike

我是 Spring Batch 框架和 quartz 调度程序的新手。我的任务是使用 quartz 调度程序动态安排新的 Spring Batch 作业。所有新的 spring batch 作业的条目都在我的数据库中,带有触发器表达式。问题是对于来自数据库的每个新的 spring 批处理作业,我们需要将它包装在 quartz 的调度程序作业中。所以意味着将有尽可能多的 spring 批处理作业,许多批处理作业类应该在那里包装它们并由 quartz 调度程序运行。

quartz 将所有作业和触发器条目存储到它自己的数据库表中。我在配置文件中进行了配置。这项工作将永远是 quartz 的工作而不是 Spring 批处理工作。这是我的主要方法,在这里我将编写我的数据库连接代码以找出新的 springbatch 作业名称和触发器表达式并将它们与 quartz schedular 绑定(bind)

 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 作业,其 execute 方法用于运行 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());

}

setJobName 方法中,我正在硬编码我的 spring 批处理作业名称,但在我的项目中,我们有将近 800 个工作岗位,因此根据方法,我们需要制作 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);
}
}
}

现在您需要通过设置 jobFactory 属性来配置 SchedulerFactoryBean 以使用 AutowiringSpringBeanJobFactory。完成后,您只需要适本地配置 quartz 作业。

对于您发布的示例,以下将在触发启动时启动 helloWorldJob

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();
}
}

注意 .usingJobData("jobName", "helloWorldJob")SpringBeanJobFactory 将尝试满足 SpringBatchJob 上的所有设置方法类(class)。这有一个 setJobName,它会在启动时注入(inject) helloWorldJob。该功能由 AutowiringSpringBeanJobFactory 扩展,还可以从 Spring Batch 自动连接所需的基础设施 bean。

如果您需要将其他属性传递给 Spring Batch 作业(如要使用的键或其他信息,只需添加另一个 usingJobData("your-property", your-value)。修改后的 SpringBatchJob 将在启 Action 业之前将所有 quarts 作业参数映射到 Spring Batch 参数。

注意:这是我凭空想出来的,我还没有实际测试过,但它至少应该让你知道如何做到这一点。

关于java - 如何使用 quartz 调度程序动态配置 spring 作业,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38389962/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com