當(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
這個(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 = ".*")}
)
原理:
- 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)代碼略)
}
- 然后在
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 = ".*")}