根据条件初始化数据源 bean

Initialize datasource bean on condition

所以,我需要根据条件来初始化DataSource。我从 .env 文件中获取所有 db-config 数据,其中有一个特殊变量 spring_profiles_active。当此变量等于“p2”时,我需要初始化 secondDataSource,否则不需要。我该怎么做呢? 我的配置:

@Configuration
public class JpaConfig {
    @Value("${jdbc.url}")
    private String jdbcUrl;
    @Value("${jdbc.username}")
    private String jdbcUsername;
    @Value("${jdbc.password}")
    private String jdbcPassword;
    @Value("${jdbc.driverClassName}")
    private String jdbcDriverClassName;

    @Value("${second.jdbc.url}")
    private String secondJdbcUrl;
    @Value("${second.jdbc.username}")
    private String secondJdbcUsername;
    @Value("${second.jdbc.password}")
    private String secondJdbcPassword;
    @Value("${second.jdbc.driverClassName}")
    private String secondJdbcDriverClassName;

    @Bean
    @Primary
    public DataSource dataSource(){
        DriverManagerDataSource dataSource = new DriverManagerDataSource();

        dataSource.setDriverClassName(jdbcDriverClassName);
        dataSource.setUrl(jdbcUrl);
        dataSource.setUsername(jdbcUsername);
        dataSource.setPassword(EncryptionUtil.decryptProperty(jdbcPassword));

        return dataSource;
    }

    @Bean
    @Qualifier("secondDataSource")
    public DataSource secondDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();

        dataSource.setDriverClassName(secondJdbcDriverClassName);
        dataSource.setUrl(secondJdbcUrl);
        dataSource.setUsername(secondJdbcUsername);
        dataSource.setPassword(EncryptionUtil.decryptProperty(secondJdbcPassword));

        return dataSource;
    }
 

    @Bean
    @Primary
    public JdbcTemplate jdbcTemplate() { return new JdbcTemplate(dataSource()); }

    @Bean
    @Qualifier("secondJdbcTemplate")
    public JdbcTemplate secondJdbcTemplate(@Qualifier("secondDataSource") DataSource secondDataSource) {
        return new JdbcTemplate(secondDataSource);
    }
}

    @Configuration
    @Conditional(SecondJpaConfigCondition.class)
    public class SecondJpaConfig {
    
        @Value("${second.jdbc.url}")
        private String secondJdbcUrl;
        @Value("${second.jdbc.username}")
        private String secondJdbcUsername;
        @Value("${second.jdbc.password}")
        private String secondJdbcPassword;
        @Value("${second.jdbc.driverClassName}")
        private String secondJdbcDriverClassName;
        
        @Bean
        @Qualifier("secondDataSource")
        public DataSource secondDataSource() {
            DriverManagerDataSource dataSource = new DriverManagerDataSource();
    
            dataSource.setDriverClassName(secondJdbcDriverClassName);
            dataSource.setUrl(secondJdbcUrl);
            dataSource.setUsername(secondJdbcUsername);
            dataSource.setPassword(EncryptionUtil.decryptProperty(secondJdbcPassword));
    
            return dataSource;
        }
        
        @Bean
        @Qualifier("secondJdbcTemplate")
        public JdbcTemplate secondJdbcTemplate(@Qualifier("secondDataSource") DataSource secondDataSource) {
            return new JdbcTemplate(secondDataSource);
        }
    }
@Component
public class SecondJpaConfigCondition implements Condition {

    @Value("${spring.profiles.active}")
    private String activeProfile;

    @Override
    public boolean matches(ConditionContext arg0, AnnotatedTypeMetadata arg1) {
        return activeProfile.equals("p2");
    }
}

我建议您使用 @ConditionalOnProperty 注释。它可以用在 class 或带有 @Bean 注释的方法上。我将在两个不同的 classes 中分离两个数据库的配置(这不是强制性的,您可以使用 secondDataSource 和 secondJdbcTemplate 方法的注释)并执行如下操作:

JpaConfig(第一个数据源):



@Configuration
public class JpaConfig {
    
    @Value("${jdbc.url}")
    private String jdbcUrl;
    @Value("${jdbc.username}")
    private String jdbcUsername;
    @Value("${jdbc.password}")
    private String jdbcPassword;
    @Value("${jdbc.driverClassName}")
    private String jdbcDriverClassName;

    @Bean
    @Primary
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();

        dataSource.setDriverClassName(jdbcDriverClassName);
        dataSource.setUrl(jdbcUrl);
        dataSource.setUsername(jdbcUsername);
        dataSource.setPassword(EncryptionUtil.decryptProperty(jdbcPassword));

        return dataSource;
    }

    @Bean
    @Primary
    public JdbcTemplate jdbcTemplate() {
        return new JdbcTemplate(dataSource());
    }

}

</pre>

JpaConditionalConfig(第二个数据源):



    @Configuration
    @ConditionalOnProperty(prefix = "cond", name = "spring_profiles_active", havingValue = "p2")
    public class JpaOptionalConfig {
    
        @Value("${second.jdbc.url}")
        private String secondJdbcUrl;
        @Value("${second.jdbc.username}")
        private String secondJdbcUsername;
        @Value("${second.jdbc.password}")
        private String secondJdbcPassword;
        @Value("${second.jdbc.driverClassName}")
        private String secondJdbcDriverClassName;
        
        @Bean
        @Qualifier("secondDataSource")
        public DataSource secondDataSource() {
            DriverManagerDataSource dataSource = new DriverManagerDataSource();
    
            dataSource.setDriverClassName(secondJdbcDriverClassName);
            dataSource.setUrl(secondJdbcUrl);
            dataSource.setUsername(secondJdbcUsername);
            dataSource.setPassword(EncryptionUtil.decryptProperty(secondJdbcPassword));
    
            return dataSource;
        }
        
        @Bean
        @Qualifier("secondJdbcTemplate")
        public JdbcTemplate secondJdbcTemplate(@Qualifier("secondDataSource") DataSource secondDataSource) {
            return new JdbcTemplate(secondDataSource);
        }
    }

</pre>

定义 spring_profiles_active 属性 的属性文件,Spring 将读取该文件以了解是否应创建条件 bean:



    jdbc.url=jdbc:h2:mem:mydb
    jdbc.username=sa
    jdbc.password=password
    jdbc.driverClassName=org.h2.Driver
    
    second.jdbc.url=jdbc:h2:mem:mydb
    second.jdbc.username=sa
    second.jdbc.password=password
    second.jdbc.driverClassName=org.h2.Driver
    
    #THIS IS THE PROPERTY USED IN THE CONDITIONAL BEANS
    conditional.spring_profiles_active=p2

</pre>