代码之家  ›  专栏  ›  技术社区  ›  user1020455

Spring Boot 2.0 Quartz-使用非主数据源

  •  9
  • user1020455  · 技术社区  · 6 年前

    我在应用程序中使用Quartz作为调度器。正在尝试使用Spring boot 2.0功能。我在配置中有两个不同的数据源。一个用于应用程序,另一个用于调度程序。如何使用非主数据源(本例中为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>
    

    应用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;
        }
    }
    

    应用Java语言

    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中的一个bug。作为一种解决方法,我移除了spring。石英作业存储区类型属性,然后在customizer中配置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);
            };
        }
    }
    
    3 回复  |  直到 6 年前
        1
  •  4
  •   user1020455    6 年前

    这是spring boot中的一个bug。作为一种解决方法,我移除了spring。石英作业存储区类型属性,然后在customizer中配置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);
            };
        }
    }
    
        2
  •  2
  •   teppic    6 年前

    您可以通过构建 SchedulerFactoryBean 您自己:

    @Bean
    public SchedulerFactoryBean schedulerFactory() {
        SchedulerFactoryBean bean = new SchedulerFactoryBean();
        bean.setDataSource(schedulerDataSource());
        return bean;
    }
    

    或者,在Spring Boot 2中,您可以使用 SchedulerFactoryBeanCustomizer 。这将允许您自定义自动配置器实例化的bean,这可能会减少工作量。

    @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);
        }
    }
    
        3
  •  0
  •   guzy    4 年前

    我通过排除DataSourceAutoConfiguration来解决这个问题。班

    @SpringBootApplication(exclude = DataSourceAutoConfiguration.class,
    

    并自定义调度器实例,如下所示:

    @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();
    }
    

    我的完整代码是 https://github.com/guzhangyu/learn-spring-cloud/tree/master/springboot-quartz