2016-07-15 61 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的參數。

注意:這是從我的頭頂打出的,我沒有真正測試過,但它至少應該給你一個關於如何做到這一點的想法。