多個(gè)spring data源(jdbc/jpa/redis/mongodb)共同使用時(shí)沖突問(wèn)題

當(dāng)項(xiàng)目里面同時(shí)使用了多個(gè)spring data源的時(shí)候spring會(huì)不知道加載那個(gè)。

spring log 信息

2022-04-03 13:28:48.978 INFO  [main] RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode!
2022-04-03 13:28:48.980 INFO  [main] RepositoryConfigurationDelegate - Bootstrapping Spring Data JDBC repositories in DEFAULT mode.
2022-04-03 13:28:49.010 INFO  [main] RepositoryConfigurationExtensionSupport - Spring Data JDBC - Could not safely identify store assignment for repository candidate interface ... If you want this repository to be a JDBC repository, consider annotating your entities with one of these annotations: org.springframework.data.relational.core.mapping.Table.

方法一給model加上對(duì)應(yīng)的注解(從根源解決)

https://docs.spring.io/spring-data/jdbc/docs/current/reference/html/#repositories.multiple-modules

  • spring-data-jdbc的注解Table
  • spring-data-mongodb的注解Document
  • spring-data-jpa的注解Entity

方法二指定掃描的包,配置文件里禁用不需要的repos

https://stackoverflow.com/questions/39432764/info-warnings-about-multiple-modules-in-spring-boot-what-do-they-mean

這個(gè)方法實(shí)際測(cè)試不生效。

@EnableJpaRepositories(basePackages = "com.acme.repositories.jpa")
@EnableMongoRepositories(basePackages = "com.acme.repositories.mongo")
spring:
  data:
    redis:
      repositories:
        enabled: false
        type: none

方法三在EnableJdbcRepositories加上includeFilters繞開(kāi)限制

@EnableJdbcRepositories(basePackages = "com.acme.repositories.jdbc",
    includeFilters = {@ComponentScan.Filter(type = FilterType.REGEX, pattern = ".*")}
)
原理:
  1. spring在RepositoryConfigurationDelegate里判斷時(shí)候有多個(gè)spring-data源的
    public List<BeanComponentDefinition> registerRepositoriesIn(BeanDefinitionRegistry registry,
            RepositoryConfigurationExtension extension) {
//...(無(wú)關(guān)代碼略)
        Collection<RepositoryConfiguration<RepositoryConfigurationSource>> configurations = extension
                .getRepositoryConfigurations(configurationSource, resourceLoader, inMultiStoreMode);
//...(無(wú)關(guān)代碼略)
    }
  1. 然后在RepositoryConfigurationExtensionSupport進(jìn)行判斷時(shí)候加載
    public <T extends RepositoryConfigurationSource> Collection<RepositoryConfiguration<T>> getRepositoryConfigurations(
            T configSource, ResourceLoader loader, boolean strictMatchesOnly) {

        Assert.notNull(configSource, "ConfigSource must not be null!");
        Assert.notNull(loader, "Loader must not be null!");

        Set<RepositoryConfiguration<T>> result = new HashSet<>();

        for (BeanDefinition candidate : configSource.getCandidates(loader)) {

            RepositoryConfiguration<T> configuration = getRepositoryConfiguration(candidate, configSource);
            Class<?> repositoryInterface = loadRepositoryInterface(configuration,
                    getConfigurationInspectionClassLoader(loader));

            if (repositoryInterface == null) {
                result.add(configuration);
                continue;
            }

            RepositoryMetadata metadata = AbstractRepositoryMetadata.getMetadata(repositoryInterface);

            boolean qualifiedForImplementation = !strictMatchesOnly || configSource.usesExplicitFilters()
                    || isStrictRepositoryCandidate(metadata);

            if (qualifiedForImplementation && useRepositoryConfiguration(metadata)) {
                result.add(configuration);
            }
        }

        return result;
    }

核心的判斷是這個(gè)

boolean qualifiedForImplementation = !strictMatchesOnly || configSource.usesExplicitFilters() || isStrictRepositoryCandidate(metadata);

  • strictMatchesOnly: 如果有多個(gè)spring-data資源這個(gè)就為true
  • configSource.usesExplicitFilters() 這個(gè)就是判斷Enable..注解includeFilters,includeFilters時(shí)候有設(shè)置

所以加上這個(gè)就能繞開(kāi)限制了

includeFilters = {@ComponentScan.Filter(type = FilterType.REGEX, pattern = ".*")}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容