2016-10-24 6 views
4

У меня есть приложение Spring Boot и вы хотите внедрить конкретные реализации репозитория на основе типа базового источника данных SQL (определенного с использованием свойств spring.datasource. *).Spring Boot: Условный тип базы данных

Я попытался использовать пользовательский условный код здесь, но, к сожалению, когда он оценивается, я не могу получить источник данных, чтобы проверить тип базы данных.

Мое состояние в настоящее время выглядит следующим образом:

@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) 

Я предполагаю, что это происходит потому, что условия on уже проверяется до того, как все бобы будут построены. Есть ли способ сообщить Spring, что источник данных должен быть создан до того, как это условие будет оценено? Или это просто невозможно использовать пружинные условия?

Вариант использования, который я хочу решить, заключается в следующем: приложение может работать с различными типами баз данных, а некоторые (например, H2) не выполняют определенные функции, такие как функции окон. Поэтому я хочу предоставлять специальные запросы для определенных баз данных, которые могут быть более медленными, но функционально правильными. Идея такого подхода заключалась в том, что эти репозитории JDBC следует легко отличить без необходимости введения конкретных профилей Spring, но просто взглянув на базовую базу данных (используя org.springframework.jdbc.support.JdbcUtils).

Благодаря

ответ

2

Некоторые условия оцениваются, когда боб на самом деле создается. Если вы хотите проверить наличие bean-компонента, вы должны быть очень осторожны, потому что любая попытка получить компонент на этом этапе приведет к ранней инициализации. Это первая проблема.

Вторая проблема заключается в том, что ваша конфигурация (конфигурация приложения) всегда запустить полностью до того авто-конфигурации. Если Spring Boot должен решить, должен ли он создать DataSource, он должен предоставить конфигурацию приложения возможность его предоставить.

Единственный способ, которым вы можете реализовать это путем автоматической настройки, убедиться, что ваша автоконфигурация выполняется после тех, которые должны предоставить компонент, который вы ищете (@AutoconfigureAfter). Независимо от того, что я бы не стал прямо обращаться к контексту. Проверьте OnBeanCondition, чтобы увидеть, как Spring Boot делает эту вещь. Таким образом, вы не можете добавить такое условие в конфигурацию своего приложения или для ваших компонентов, сканируемых при сканировании компонентов.

Сказав это, прецедент выглядит довольно странно для меня. Возможно, мы могли бы сделать шаг назад, и вы могли бы объяснить, зачем вам это нужно.

+0

Привет @Stephane, я обновил вопрос с использованием оригинального варианта использования. Моя главная задача заключалась в том, чтобы создать способ разрешить различные реализации репозитория для разных баз данных (при необходимости). Я не знаю, есть ли лучшая практика, которую использует Spring (например,) - исследование Google не показало ничего полезного. –

+0

Хорошо. Вместо того, чтобы запрашивать детали реализации, я бы создал отдельный поток с тегом «spring-data» и спросил, как вы могли бы добиться этого.Я предполагаю, что некоторые запросы могут быть экстернализированы или вы можете настроить фабрику, которая создает репозиторий. Это зависит от того, какие функции используются весенними данными, если вы это сделаете. –

+1

Приложение представляет собой смесь данных пружины и пружины jdbc (где JPA недостаточно), и проблема заключается в части приложения jdbc. Я постараюсь решить проблему по-другому и вернуться с новым вопросом, если у меня возникнут проблемы. –

Смежные вопросы