Spring Boot:数据库类型

时间:2016-10-24 11:57:22

标签: java spring spring-boot

我有一个Spring Boot应用程序,并希望根据底层SQL数据源的类型(使用spring.datasource。*属性定义)注入特定的存储库实现。

我试图在这里使用自定义条件,但不幸的是,当它被评估时,我无法获取数据源以检查数据库类型。

我的情况目前如下:

@Order(Ordered.LOWEST_PRECEDENCE - 10)
class OnDatabaseTypeCondition implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {

        DataSource dataSource = context.getBeanFactory().getBean(DataSource.class);
        // further matching code here

}

应该使用类似的东西:

@ConditionalOnDatabaseType(H2)
public class MyCustomImplementation implements MyRepository {
    // Code
}

但是,在评估条件时,我得到一个未定义数据源的异常:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] is defined
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:348)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:335)

我认为这种情况正在发生,因为在构造所有bean之前已经检查了条件。有什么办法可以告诉Spring在评估这个条件之前必须创建数据源吗?或者使用Spring条件这是不可能的?

我想通过以下方式解决的用例如下:应用程序可以使用不同类型的数据库运行,而某些(如H2)不具有某些功能,如窗口函数。所以我想为某些可能较慢但功能正常的数据库提供特殊查询。这种方法的想法是,这些JDBC存储库应该易于标记而无需引入特定的Spring配置文件,只需查看底层数据库(使用org.springframework.jdbc.support.JdbcUtils)。

由于

1 个答案:

答案 0 :(得分:2)

实际创建bean时会评估某些条件。如果要检查是否存在bean,则需要非常小心,因为在该阶段获取bean的任何尝试都将导致早期初始化。这是第一个问题。

第二个问题是您的配置(应用配置)总是在自动配置之前完全运行。如果Spring Boot必须决定是否必须创建DataSource,那么它应该为应用程序配置提供一个机会。

您可以实现的唯一方法是通过自动配置,确保您的自动配置在应该提供您正在寻找的bean(@AutoconfigureAfter)之后运行。无论我不打算直接调用这样的上下文。检查OnBeanCondition以查看Spring Boot本身是如何做的。因此,您无法在应用配置或组件扫描扫描的组件中添加此类条件。

话虽如此,用例看起来很奇怪。也许我们可以退后一步,你可以解释为什么你需要这样做。