I used Quartz as scheduler in my application. Trying to use Spring boot 2.0 features. I have 2 different data sources in the configuration. One for application and another one f
This is a bug in spring-boot. As a workaround, I removed spring.quartz.job-store-type property and then configured DataSource and PlatformTransactionManager in customizer. Refer below updated code:
@Configuration
public class SchedulerConfig
{
private DataSource dataSource;
private PlatformTransactionManager transactionManager;
@Autowired
public SchedulerConfig(@Qualifier("schedulerDataSource") DataSource dataSource, @Qualifier("schedulerTransactionManager") PlatformTransactionManager transactionManager)
{
this.dataSource = dataSource;
this.transactionManager = transactionManager;
}
@Bean
public SchedulerFactoryBeanCustomizer schedulerFactoryBeanCustomizer()
{
return bean ->
{
bean.setDataSource(dataSource);
bean.setTransactionManager(transactionManager);
};
}
}
I solve this problem by excluding DataSourceAutoConfiguration.class
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class,
and customize the scheduler instance as following:
@Bean("qzDataSource")
@Qualifier("qzDataSource")
public HikariDataSource qzDataSource() {
return qzDataSourceProperties().initializeDataSourceBuilder()
.type(HikariDataSource.class).build();
}
@Bean
public PlatformTransactionManager quartzDataSourceTransactionManager(@Qualifier("qzDataSource") DataSource qzDataSource) {
final DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(qzDataSource);
return transactionManager;
}
@Bean
public SchedulerFactoryBean schedulerFactory(@Qualifier("qzDataSource") DataSource qzDataSource) {
SchedulerFactoryBean bean = new SchedulerFactoryBean();
bean.setDataSource(qzDataSource);
bean.setTransactionManager(quartzDataSourceTransactionManager(qzDataSource));
return bean;
}
@Bean
public Scheduler scheduler() {
return schedulerFactory(qzDataSource()).getScheduler();
}
My full code is https://github.com/guzhangyu/learn-spring-cloud/tree/master/springboot-quartz
You could customise the datasource by building the SchedulerFactoryBean
yourself:
@Bean
public SchedulerFactoryBean schedulerFactory() {
SchedulerFactoryBean bean = new SchedulerFactoryBean();
bean.setDataSource(schedulerDataSource());
return bean;
}
Or, in Spring Boot 2, you can use a SchedulerFactoryBeanCustomizer
. This will allow you customise the bean instantiated by the autoconfigurer, which may be less work.
@Configuration
public class SchedulerConfig {
DataSource dataSource;
@Autowired
public SchedulerConfig(@Qualifier("scheduler.datasource") DataSource dataSource) {
this.dataSource = dataSource;
}
@Bean
public SchedulerFactoryBeanCustomizer schedulerFactoryBeanCustomizer()
{
return bean -> bean.setDataSource(dataSource);
}
}