2016-11-11 51 views
1

我見過很多Spring Batch項目的例子,其中(a)定義了數據源,或者(b)沒有定義數據源。我想創建一個批處理不使用我的數據源的spring批處理項目

但是,在我的項目中,我希望自己的業務邏輯能夠訪問數據源,但是我希望Spring Batch不使用數據源。這可能嗎?

這傢伙有一個類似的問題:Spring boot + spring batch without DataSource

+0

我回答了另一個問題(因爲複製StackOverflow上的問題是不可取的):http://stackoverflow.com/a/40680502/618059 –

+0

可能複製[Spring引導+沒有DataSource的Spring批處理](http://stackoverflow.com/questions/39913918/spring-boot-spring-batch-without-datasource) –

+0

讓我澄清 - 我想爲我的業務使用一個數據源邏輯,但我不希望Spring Batch使用數據源。我提供的鏈接是另一個問題,那個人只是不想使用任何* dataSource。我的問題不是重複的。 – wiltonio

回答

1

一般情況下,使用彈簧批處理沒有數據庫是不是一個好主意,因爲有可能是取決於你定義的作業類型的併發問題。因此,強烈建議至少使用內存分貝,尤其是如果您計劃在生產中使用該作業。

如果您不配置自己的數據源,SpringBoot將使用SpringBatch將初始化內存數據源。

考慮到這一點,讓我重新定義您的問題,如下所示:我的businesslogic是否可以使用另一個數據源,而不是springbatch用來更新其BATCH表? 是的,它可以。事實上,您可以在SpringBatch作業中使用盡可能多的數據源。只需使用名義自動裝配。

這是我如何做到這一點: 我經常使用配置類,它定義了所有我在我的職位

Configuration 
public class DatasourceConfiguration { 

    @Bean 
    @ConditionalOnMissingBean(name = "dataSource") 
    public DataSource dataSource() { 
     // create datasource, that is used by springbatch 
     // for instance, create an inmemory datasource using the 
     // EmbeddedDatabaseFactory 
     return ...; 
    } 

    @Bean 
    @ConditionalOnMissingBean(name = "bl1datasource") 
    public DataSource bl1datasource() { 
     return ...; // your first datasource that is used in your businesslogic 
    } 

    @Bean 
    @ConditionalOnMissingBean(name = "bl2datasource") 
    public DataSource bl2datasource() { 
     return ...; // your second datasource that is used in your businesslogic 
    } 
} 
使用數據源

三點要注意:

SpringBatch正在尋找一個名爲「dataSource」的數據源,如果你不提供這個EXACT(大寫'S')名字作爲名字,spring批處理會嘗試按類型自動裝載,如果它發現多個DataSource實例,它會拋出一個例外。

將您的數據源配置放在它自己的類中。不要把它們和你的工作定義放在同一個班上。在加載上下文時,Spring需要能夠很早實例化名稱爲「dataSource」的數據源--SpringBean。在它開始實例化你的工作和步豆之前。如果將數據源定義放在與您的作業/步驟定義相同的類中,Spring將無法正確執行此操作。

使用@ConditionalOnMissingBean不是強制性的,但我發現它是一個很好的實踐。它可以輕鬆更改單元/集成測試的數據源。只要提供你的單位的ContextConfiguration額外的測試配置/ IT測試哪些,例如,將覆蓋「bl1Datasource」與inMemoryDataSource:

Configuration 
public class TestBL1DatasourceConfiguration { 

    // overwritting bl1datasource with an inMemoryDatasource. 
    @Bean 
    public DataSource bl1datasource() { 
     return new EmbeddedDatabaseFactory.getDatabase(); 
    } 
} 

爲了使用businesslogic數據源,通過名稱中使用注射:

@Component 
public class PrepareRe1Re2BezStepCreatorComponent { 

    @Autowired 
    private StepBuilderFactory stepBuilderFactory; 

    @Autowired 
    private DataSource bl1datasource; 

    @Autowired 
    private DataSource bl2datasource; 

    public Step createStep() throws Exception { 
     SimpleStepBuilder<..., ...> builder = 
       stepBuilderFactory.get("astep") // 
       .<..., ...> chunk(100) // 
       .reader(createReader(bl1datasource)) // 
       .writer(createWriter(bl2datasource)); // 

     return builder.build(); 
    } 
} 

此外,如果您想使用多個數據源,您可能需要考慮使用XA-Datasources。

編輯:

因爲它看來你真的不希望使用數據源,你必須實現自己的BatchConfigurer(http://docs.spring.io/spring-batch/trunk/apidocs/org/springframework/batch/core/configuration/annotation/BatchConfigurer.html)(邁克爾·米內拉 - 在SpringBatch項目負責人 - 上面所指出的)。

您可以使用org.springframework.batch.core.configuration.annotation.DefaultBatchConfigurer的代碼作爲自己實現的起點。只需刪除所有數據源/事務管理器代碼,並將if (datasource === null)部分的內容保留在初始化方法中。這將初始化一個MapBasedJobRepository和MapBasedJobExplorer。但是,再次,這不是一個有效的解決方案,因爲它不是線程安全的。

編輯:

如何實現它:

的配置類,定義了 「businessDataSource」:

@Configuration 
public class DataSourceConfigurationSimple { 
    DataSource embeddedDataSource; 

    @Bean 
    public DataSource myBusinessDataSource() { 
     if (embeddedDataSource == null) { 
      EmbeddedDatabaseFactory factory = new EmbeddedDatabaseFactory(); 
      embeddedDataSource = factory.getDatabase(); 
     } 
     return embeddedDataSource; 
    } 
} 

特定BatchConfigurer的實現: (當然,方法必須實施......)

public class MyBatchConfigurer implements BatchConfigurer { 
    @Override 
    public JobRepository getJobRepository() throws Exception { 
     return null; 
    } 

    @Override 
    public PlatformTransactionManager getTransactionManager() throws Exception { 
     return null; 
    } 

    @Override 
    public JobLauncher getJobLauncher() throws Exception { 
     return null; 
    } 

    @Override 
    public JobExplorer getJobExplorer() throws Exception { 
     return null; 
    } 
} 

最後的主要配置和啓動類:

@SpringBootApplication 
@Configuration 
@EnableBatchProcessing 

// Importing MyBatchConfigurer will install your BatchConfigurer instead of 
// SpringBatch default configurer. 
@Import({DataSourceConfigurationSimple.class, MyBatchConfigurer.class}) 

public class SimpleTestJob { 

    @Autowired 
    private JobBuilderFactory jobs; 

    @Autowired 
    private StepBuilderFactory steps; 

    @Bean 
    public Job job() throws Exception { 
     SimpleJobBuilder standardJob = this.jobs.get(JOB_NAME) 
               .start(step1()); 
     return standardJob.build(); 
    } 

    protected Step step1() throws Exception { 
     TaskletStepBuilder standardStep1 = this.steps.get("SimpleTest_step1_Step") 
                .tasklet(tasklet()); 
     return standardStep1.build(); 
    } 

    protected Tasklet tasklet() { 
     return (contribution, context) -> { 
      System.out.println("tasklet called"); 
      return RepeatStatus.FINISHED; 
     }; 
    } 

    public static void main(String[] args) throws Exception { 
     SpringApplication.run(SimpleTestJob.class, args); 
    } 
} 
+0

您已經展示瞭如何配置Spring Batch以使用與我用於業務邏輯的數據源不同的數據源。這不是我問的。我問是否可以阻止Spring Batch使用數據源,同時仍然使用數據源來處理業務邏輯。 – wiltonio

+0

我知道,因爲這是你應該要求的。 :-)正如我在答覆開始時指出的那樣,有很好的理由說明爲什麼你至少應該在spring批處理中使用內存分區。但無論如何,我在如何編寫自己的BatchConfigurer時添加了一些註釋。 –

+0

謝謝你最終試圖回答我的問題。讓我問你這個問題:你實際上是否使用你的解決方案獲得了實施?因爲我已經嘗試創建一個自定義的BatchConfigurer,並且它不起作用。 – wiltonio

相關問題