2016-07-15 64 views
2

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

石英正在存储所有作业并触发进入其自己的数据库表。我已经在配置文件中进行了配置。这项工作永远是石英的工作,而不是春季批量工作。 这里是我的主要方法,在这里,我会写我的数据库连接代码,找出新的springbatch作业名称,并触发表达,将它们绑定石英程序器

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这是石英作业,并且其执行方法用于运行弹簧批处理作业。

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方法,我硬编码我春天批处理作业名称, 但在我的项目我们有近800个职位,所以ACC到approarch我们需要800包装类。

请帮助我,如何通过制作泛型类来解决此问题。

回答

4

我真诚地希望你没有真正使用这个类,它会最终吃掉你所有的内存,因为你一遍又一遍地重新创建你的应用程序。

春天已经支持石英,尤其是作为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); 
     } 
    } 
} 

现在你需要将SchedulerFactoryBean配置通过设置jobFactory财产使用AutowiringSpringBeanJobFactory。当你完成后,你只需要适当地配置石英工作。

对于您发布的样本,当它被触发启动时,以下将启动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类的所有setter方法。这有一个setJobName,它将在启动时注入helloWorldJob。该功能由AutowiringSpringBeanJobFactory扩展为自动连接Spring Batch所需的基础架构Bean。

如果您需要通过额外的性质春季批处理作业(如按键,使用或其他信息,只需添加另一个usingJobData("your-property", your-value)。修改后的SpringBatchJob将所有夸脱的工作参数映射启动作业之前Spring Batch的参数。

注意:这是从我的头顶打出的,我没有真正测试过,但它至少应该给你一个关于如何做到这一点的想法。