我見過很多Spring Batch項目的例子,其中(a)定義了數據源,或者(b)沒有定義數據源。我想創建一個批處理不使用我的數據源的spring批處理項目
但是,在我的項目中,我希望自己的業務邏輯能夠訪問數據源,但是我希望Spring Batch不使用數據源。這可能嗎?
這傢伙有一個類似的問題:Spring boot + spring batch without DataSource
我見過很多Spring Batch項目的例子,其中(a)定義了數據源,或者(b)沒有定義數據源。我想創建一個批處理不使用我的數據源的spring批處理項目
但是,在我的項目中,我希望自己的業務邏輯能夠訪問數據源,但是我希望Spring Batch不使用數據源。這可能嗎?
這傢伙有一個類似的問題:Spring boot + spring batch without DataSource
一般情況下,使用彈簧批處理沒有數據庫是不是一個好主意,因爲有可能是取決於你定義的作業類型的併發問題。因此,強烈建議至少使用內存分貝,尤其是如果您計劃在生產中使用該作業。
如果您不配置自己的數據源,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);
}
}
您已經展示瞭如何配置Spring Batch以使用與我用於業務邏輯的數據源不同的數據源。這不是我問的。我問是否可以阻止Spring Batch使用數據源,同時仍然使用數據源來處理業務邏輯。 – wiltonio
我知道,因爲這是你應該要求的。 :-)正如我在答覆開始時指出的那樣,有很好的理由說明爲什麼你至少應該在spring批處理中使用內存分區。但無論如何,我在如何編寫自己的BatchConfigurer時添加了一些註釋。 –
謝謝你最終試圖回答我的問題。讓我問你這個問題:你實際上是否使用你的解決方案獲得了實施?因爲我已經嘗試創建一個自定義的BatchConfigurer,並且它不起作用。 – wiltonio
我回答了另一個問題(因爲複製StackOverflow上的問題是不可取的):http://stackoverflow.com/a/40680502/618059 –
可能複製[Spring引導+沒有DataSource的Spring批處理](http://stackoverflow.com/questions/39913918/spring-boot-spring-batch-without-datasource) –
讓我澄清 - 我想爲我的業務使用一個數據源邏輯,但我不希望Spring Batch使用數據源。我提供的鏈接是另一個問題,那個人只是不想使用任何* dataSource。我的問題不是重複的。 – wiltonio