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

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将所有作业和触发器条目存储到自己的数据库表中。我在配置

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

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

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