Open commonquail opened 5 months ago
I think we could achieve this by having SpringBootBatchConfiguration
override the @Bean
methods that are declared in DefaultBatchConfiguration
and marking them as @ConditionalOnMissingBean
. This would be similar to what we've done for some Spring MVC-related beans:
@wilkinsona correct me if I'm wrong, but this won't work because then you'd get duplicate beans: one from the superclass an one from your subclass.
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@SpringBootApplication
class DemoApplication
fun main(args: Array<String>) {
val context = SpringApplication.run(DemoApplication::class.java, *args)
println(context.getBean("text"))
}
@Configuration(proxyBeanMethods = false)
class SuperBeans {
@Bean
fun text() = "Hello"
}
@Configuration(proxyBeanMethods = false)
class SubBeans : SuperBeans() {
@Bean
override fun text() = "World"
}
Results in
org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'text' defined in class path resource [...] since there is already [...]
@micheljung this works fine as shown by the Spring MVC example to which I have linked above. The arrangement you've shown isn't the same as we've used in EnableWebMvcConfiguration
. You're using component scanning which means that both SubBeans
and SuperBeans
are registered as configuration classes. In the auto-configuration case, only EnableWebMvcConfiguration
is registered. DelegatingWebMvcConfiguration
, that it extends, is not registered. In the batch case, SpringBootBatchConfiguration
would be registered but DefaultBatchConfiguration
would not be.
This is a valid point. Currently, as a boot user, I can provide a batch datasource and it will be set on the job repository, without having to (re)define the job repository. I should be able to do the same with the task executor of the job launcher, meaning I should be able to specify a task executor to use for batch without having to define the job launcher.
However, in my experience with users mixing web requests and batch workloads (ie running batch jobs in the same JVM as the servlet container), it is common that people do not want to use the same thread pool for web and batch requests (different pool sizes, different prefixes, etc). Therefore, it should be possible to specify a dedicated task executor for batch. What about a new annotation @BatchTaskExecutor
similar to the one for the datasource and transaction manager?
This is #1655 again, with the catch that
BatchConfigurer
(BasicBatchConfigurer
?) is not available in Spring Boot 3. Therefore, the Spring Boot autoconfigured Spring BatchJobLauncher
'sTaskExecutor
cannot be directly customized at all. Users can only provide an alternativeJobLauncher
bean, as demonstrated in that issue, or forgo Spring Boot's autoconfiguration entirely.The practical impact of this does not appear significant. It is evident from inspecting the autoconfiguration that it is aimed at command line runners, where synchronous execution seems reasonable to me. In a web context synchronous execution is possibly an acceptable default (debatable, but all right) but the inability to switch to asynchronous execution is not acceptable, however, the autoconfiguration does not help a web context much at all so opting out of it is a minor issue.
Although I think the executor should be possible to configure I might well argue that the bigger issue is that the Spring Boot reference documentation could be clearer about where the autoconfiguration is useful and where it is preferable to skip it.