我在应用程序中使用Quartz作为调度程序。尝试使用Spring Boot 2.0功能。我在配置中有2个不同的数据源。一个用于应用程序,另一个用于调度程序。如何使用非主要数据源(在这种情况下为SchedulerDataSource)作为Quartz的数据源?请帮忙。
pom.xml
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.0.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency> <dependency> <groupId>com.oracle</groupId> <artifactId>wlthint3client</artifactId> <version>12.2.1.2</version> <scope>system</scope> <systemPath>C:/Oracle/products/mw_home/wlserver/server/lib/wlthint3client.jar</systemPath> </dependency> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc</artifactId> <version>7</version> <scope>system</scope> <systemPath>C:/Oracle/products/mw_home/oracle_common/modules/oracle.jdbc/ojdbc7.jar</systemPath> </dependency> </dependencies>
application.yml
spring: quartz: job-store-type: jdbc jdbc: initialize-schema: never properties: org: quartz: scheduler: instanceName: ETL threadPool: threadCount: 50 jobStore: class: org.quartz.impl.jdbcjobstore.JobStoreTX driverDelegateClass: org.quartz.impl.jdbcjobstore.oracle.OracleDelegate tablePrefix: QRTZ_ useProperties: true scheduler: datasource: url: jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=XXXXXX)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=XXXX))) username: scheduler password: XXXXXX driver-class-name: oracle.jdbc.OracleDriver t3: datasource: url: jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=XXXXXX)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=XXXXXX))) username: app password: XXXXXX driver-class-name: oracle.jdbc.OracleDriver
AppDataSource.java
@Configuration public class AppDataSource { @Bean @Primary @ConfigurationProperties("t3.datasource") public DataSourceProperties t3DataSourceProperties() { return new DataSourceProperties(); } @Bean @Primary @ConfigurationProperties("t3.datasource") public HikariDataSource t3DataSource() { return t3DataSourceProperties().initializeDataSourceBuilder().type(HikariDataSource.class).build(); } @Bean @ConfigurationProperties("scheduler.datasource") public DataSourceProperties schedulerDataSourceProperties() { return new DataSourceProperties(); } @Bean @ConfigurationProperties("scheduler.datasource") public HikariDataSource schedulerDataSource() { return schedulerDataSourceProperties().initializeDataSourceBuilder().type(HikariDataSource.class).build(); } @Bean public PlatformTransactionManager schedulerTransactionManager() { final DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(); transactionManager.setDataSource(schedulerDataSource()); return transactionManager; } }
应用程序
package com.aaa.t3.starter; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; import org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration; import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.ComponentScan; import com.spdji.aaa.jms.JmsService; @ComponentScan("com.aaa.t3") @SpringBootApplication(exclude = { ActiveMQAutoConfiguration.class, JmxAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class }) public class Application { public static void main(String[] args) { ApplicationContext context = SpringApplication.run(Application.class, args); JmsService jmsService = (JmsService) context.getBean("jmsService"); jmsService.sendMessage(); /*String[] beans = context.getBeanDefinitionNames(); Arrays.stream(beans).sorted().forEach(System.out::println);*/ } }
试图使用SchedulerFactoryBeanCustomizer修改数据源,但仍引用主数据源。
@Configuration public class SchedulerConfig { private DataSource dataSource; @Autowired public SchedulerConfig(@Qualifier("schedulerDataSource") DataSource dataSource) { this.dataSource = dataSource; } @Bean public SchedulerFactoryBeanCustomizer schedulerFactoryBeanCustomizer() { return bean -> bean.setDataSource(dataSource); } }
使用调试器验证。SchedulerConfig中的自动装配数据源是调度程序数据源,但此后已被覆盖。在QuartzAutoConfiguration.quartzDataSourceInitializer中添加了断点,并检查了数据源。这不是调度程序数据源。这已被主要数据源覆盖。Quartz自动配置将覆盖SchedulerFactoryBeanCustomizer定制。我已经打开github.com/spring- projects/spring-boot/issues/12780修复它。
这是spring-boot中的错误。解决方法是,删除spring.quartz.job-store- type属性,然后在定制程序中配置DataSource和PlatformTransactionManager。请参阅下面的更新代码:
@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); }; } }