2015-12-01 30 views
7

Vì "Chỉ có phương thức trả lại void có thể được chú thích bằng @Scheduled", làm cách nào để sử dụng Công cụ lập lịch Spring và Spring Scheduler khi tôi đang sử dụng cấu hình @Bean thay vì cấu hình xml? Bên dưới, bạn có thể tìm thấy tệp cấu hình hoàn chỉnh của mình. Nó đang chạy hoàn hảo khi tôi kích hoạt từ main() nhưng chỉ một lần. Tôi muốn thêm @Scheduled(fixedrate=9999) để gợi lên công việc tương tự ở tần suất nhất định. Theo như tôi có thể thấy, để làm điều này, tôi đã dự kiến ​​sẽ thêm @Scheduled xung quanh phương thức step1 nhưng tôi không thể vì nó trả về khác nhau từ void.Cách sử dụng @Configuration và @EnableScheduling cùng với Spring Batch

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

Trả lời

4

Chỉ cần tạo thành phần riêng biệt, nơi bạn autowire công việc của bạn và lập lịch:

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

Phản ứng đối với nhận xét thứ ba:

Chỉ cần sử dụng .allowStartIfComplete(true) khi bạn đang tạo bước.

+0

Tôi nhận được hai cảnh báo: 1 - (chuột phải vào @Scheduled) Chú thích @Scheduled là không được phép cho vị trí này 2 - (chuột phải vào phương pháp runJob) Nhiều dấu tại dòng này - Cú pháp lỗi, chèn ";" để hoàn thành FieldDeclaration - void là loại không hợp lệ cho biến số runJob Tôi đã cập nhật câu hỏi của mình khi thêm đề xuất của bạn. Tôi đã cho thấy việc nhập khẩu cũng như các cảnh báo như vậy thường xuất hiện khi chúng tôi không có hàng nhập khẩu chính xác nhưng tôi đoán là tôi đã đúng. Tôi có nên thêm @SuppressWarnings không? –

+1

Tôi bỏ ngoặc cho phương thức runJob(). Nó được cập nhật ngay bây giờ. – luboskrnac

+0

Tôi có thể thấy lịch trình đang hoạt động nhưng tôi đang nhận được SimpleStepHandler: Bước đã hoàn thành hoặc không thể khởi động lại, vì vậy không có hành động nào để thực thi: 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 =. Dường như với tôi rằng sau khi công việc của tôi chạy hai lần, nó không thể chạy được nữa. Tôi đoán, lần đầu tiên chạy khi tôi khởi động ứng dụng, sau đó lần thứ hai là trình kích hoạt lịch trình. Sau đó, trạng thái "hoàn thành" mãi mãi. –

Các vấn đề liên quan