2015-12-01 68 views
7

"Yalnız döndürme yöntemleri @Scheduled ile açıklanabileceğinden", xml yapılandırması yerine @Bean yapılandırması kullandığımda Spring Batch ve Spring Scheduler Görevini nasıl kullanabilirim? Aşağıda tüm yapılandırma dosyasını bulabilirsiniz. main()'dan başladığımda sadece bir kez çalışıyor. Belirli bir frekansta aynı işi uyandırmak için @Scheduled(fixedrate=9999)'u eklemek istiyorum. Görebildiğim kadarıyla, bunu yapabilmek için, adım 1 yöntemi etrafında @Scheduled eklemem bekleniyordu, ancak void'den farklı olarak döndüremiyorum. Üçüncü yorumumSpring Batch ile birlikte @Configuration ve @EnableScheduling nasıl kullanılır

@Component 
public class MyScheduler{ 
    private Job myImportJob; 
    private JobLauncher jobLauncher; 

    @Autowired 
    public MyScheduler(JobLauncher jobLauncher, @Qualifier("myImportJob") Job myImportJob){ 
     this.myImportJob = myImoportJob; 
     this.jobLauncher = jobLauncher; 
    } 

    @Scheduled(fixedRate=9999) 
    public void runJob(){ 
     jobLauncher.run(myImportJob, new JobParameters()); 
    } 
} 

: Reaksiyon: adımı oluştururken

Sadece .allowStartIfComplete(true) kullanmak

@Configuration 
@EnableBatchProcessing 
@EnableScheduling 
public class BatchConfiguration { 
     private static final Logger log = LoggerFactory 
        .getLogger(BatchConfiguration.class); 

     @Bean 
     @StepScope 
     public FlatFileItemReader<Person> reader() { 
       log.info(new Date().toString()); 
       FlatFileItemReader<Person> reader = new FlatFileItemReader<Person>(); 
       reader.setResource(new ClassPathResource("test_person_json.js")); 
       reader.setLineMapper(new DefaultLineMapper<Person>() { 
        { 
          setLineTokenizer(new DelimitedLineTokenizer() { 
            { 
             setNames(new String[] {"firstName", "lastName" }); 
            } 
          }); 
          setFieldSetMapper(new BeanWrapperFieldSetMapper<Person>() { 
            { 
             setTargetType(Person.class); 
            } 
          }); 
        } 
       }); 
       return reader; 
     } 

     @Bean 
     public ItemProcessor<Person, Person> processor() { 
       return new PersonItemProcessor(); 
     } 

     @Bean 
     public ItemWriter<Person> writer(DataSource dataSource) { 
       JdbcBatchItemWriter<Person> writer = new JdbcBatchItemWriter<Person>(); 
       writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<Person>()); 
       writer.setSql("INSERT INTO people (first_name, last_name) VALUES (:firstName, :lastName)"); 
       writer.setDataSource(dataSource); 
       return writer; 
     } 

     @Bean 
     public Job importUserJob(JobBuilderFactory jobs, Step s1, 
        JobExecutionListener listener) { 
       return jobs.get("importUserJob").incrementer(new RunIdIncrementer()) 
          .listener(listener).flow(s1).end().build(); 
     } 

     @Bean 
     public Step step1(StepBuilderFactory stepBuilderFactory, 
        ItemReader<Person> reader, ItemWriter<Person> writer, 
        ItemProcessor<Person, Person> processor) { 
       return stepBuilderFactory.get("step1").<Person, Person> chunk(10) 
.reader(reader).processor(processor).writer(writer).build(); 
     } 

     @Bean 
     public JdbcTemplate jdbcTemplate(DataSource dataSource) { 
       return new JdbcTemplate(dataSource); 
     } 
} 


//Question updated on Dec 3th 2015 with first suggestion 
import org.springframework.batch.core.Job; 
import org.springframework.batch.core.JobParameters; 
import org.springframework.batch.core.launch.JobLauncher; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.beans.factory.annotation.Qualifier; 
import org.springframework.scheduling.annotation.Scheduled; 
import org.springframework.stereotype.Component; 

@Component 
public class PersonScheduler { 
    private Job myImportJob; 
    private JobLauncher jobLauncher; 

    @Autowired 
    public PersonScheduler(JobLauncher jobLauncher, @Qualifier("myImportJob") Job myImportJob){ 
     this.myImportJob = myImportJob; 
     this.jobLauncher = jobLauncher; 
    } 

    @Scheduled(fixedRate=9999) 
    public void runJob{ 
     jobLauncher.run(myImportJob, new JobParameters()); 
    } 
} 

cevap

4

Sadece işinizi autowire ve planlayın ayrı bileşeni oluşturun.

+0

Ben iki uyarı alıyorum: 1 - @Scheduled bu konum için izin verilmese açıklama (sağ @Scheduled üzerine) 2 - (sağ yöntem runJob üzerine) bu çizgide Çoklu belirteçler - Sözdizimi hatası, insert ";" - FieldDeclaration - void runJob için geçersiz bir örnektir. Soruyu öneri olarak ekledim. İthalatın yanı sıra, genellikle doğru ithalata sahip olmadığımız zaman bu tür uyarılar göründüğümü gösterdim ama sanırım bu konuda haklıyım. @SuppressWarnings'i eklemeli miyim? –

+1

runJob() yöntemi için forget parantezleri. Şimdi güncellendi. – luboskrnac

+0

Zamanlayıcının çalıştığını görebiliyorum ancak SimpleStepHandler: Adım zaten tamamlanmış veya yeniden başlatılamıyor, bu nedenle yürütecek işlem yok: StepExecution: id = 1, version = 3, name = step1, status = COMPLETED, exitStatus = COMPLETED, readCount = 1, filterCount = 0, writeCount = 1 readSkipCount = 0, writeSkipCount = 0, processSkipCount = 0, commitCount = 1, rollbackCount = 0, exitDescription =. Bana öyle geliyor ki, işim iki kere geçtikten sonra artık koşamaz. Sanırım, uygulamayı başladığımda ilk kez koşuyor, sonra programlayıcı tetikledikçe ikinci oluyor. Bundan sonra statü sonsuza dek "tamamlandı". –

İlgili konular