Multiple Spring Data modules found, entering strict repository configuration mode!

背景

Springboot項目在啓動時,控制檯輸出日誌:git

2019-05-28 15:28:32.439 INFO  main [org.springframework.data.repository.config.RepositoryConfigurationDelegate:165]-Multiple Spring Data modules found, entering strict repository configuration mode!
2019-05-28 15:28:32.596 INFO  main [org.springframework.data.repository.config.RepositoryConfigurationDelegate:165]-Multiple Spring Data modules found, entering strict repository configuration mode!

雖然說是INFO級別,可是憑白輸出個帶「!」的提醒信息仍是讓人難免好奇,同時更多的會顧及這個提醒是否是架構的一些不穩定的因素。爲此筆者決定一探究竟!github

分析

  • 根據控制檯報文能夠看到,日誌是從RepositoryConfigurationDelegate類中打印出來的,而根據類路徑名稱大概知道類是歸屬spring-data相關包,用IDEA很容易定位到該類是在spring-data-commons包中。
  • 該提示信息輸出了兩遍,莫非是包存在引用衝突??打開pom.xml文件,查看依賴圖pom.xml依賴圖 spring-data-commons包並未有依賴衝突。那隻好看RepositoryConfigurationDelegate具體實現了。
  • spring-data-commons.jar項目中使用的是1.13.10.RELEASE版本。爲了查看方便,找到spring官網提供的github源碼地址,並fork,最後本地導入spring-data-commons工程。 https://github.com/spring-projects/spring-data-commons.git spring-data-commons RepositoryConfigurationDelegate類的multipleStoresDetected方法打印出了該提示信息。
private static final String MULTIPLE_MODULES = "Multiple Spring Data modules found, entering strict repository configuration mode!";

	/**
	 * 掃描jar,找出RepositoryFactorySupport接口的實現類,若是RepositoryFactorySupport接口實現類不止一個則打印提示信息「MULTIPLE_MODULES」。
	 * 
	 * Scans {@code repository.support} packages for implementations of {@link RepositoryFactorySupport}. Finding more
	 * than a single type is considered a multi-store configuration scenario which will trigger stricter repository
	 * scanning.
	 *
	 * @return
	 */
	private boolean multipleStoresDetected() {

		boolean multipleModulesFound = SpringFactoriesLoader
				.loadFactoryNames(RepositoryFactorySupport.class, resourceLoader.getClassLoader()).size() > 1;

		if (multipleModulesFound) {
			LOG.info(MULTIPLE_MODULES);
		}

		return multipleModulesFound;
	}

方法中SpringFactoriesLoader.loadFactoryNames(RepositoryFactorySupport.class, resourceLoader.getClassLoader()) 是spring.factories機制的重要實現,會查找全部jar包中META-INF/spring.factories文件配置信息。經過對loadFactoryNames方法斷點調試,最終肯定了在spring-boot-starter-data-redis和spring-boot-starter-data-mongodb相關依賴包中都配置了RepositoryFactorySupport接口實現類。 spring-data-keyvalue.jarweb

org.springframework.data.repository.core.support.RepositoryFactorySupport=org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactory

spring-data-mongo.jarredis

org.springframework.data.web.config.SpringDataJacksonModules=org.springframework.data.mongodb.core.GeoJsonConfiguration
org.springframework.data.repository.core.support.RepositoryFactorySupport=org.springframework.data.mongodb.repository.support.MongoRepositoryFactory
  • KeyValueRepositoryFactory和MongoRepositoryFactory做爲RepositoryFactorySupport接口的多個實現類在設計上並無什麼問題。 ==可是對Repository功能須要特別注意了== 若是沒有使用Repository功能,那麼能夠經過配置application.yml屬性關閉repository功能,以下:
spring:
     data: 
        mongodb: 
            repositories: 
                enabled: false
        redis:
            repositories:
                enabled: false

或者啓動類中排除repository自動裝載,以下:spring

@SpringBootApplication(exclude = { RedisRepositoriesAutoConfiguration.class, MongoRepositoriesAutoConfiguration.class })

此處列舉的是redis和mongo,其餘jpa、es等配置都是相似的。關閉了Repository功能後,控制就不會在打印出Multiple Spring Data modules found, entering strict repository configuration mode!的提示信息了。mongodb

若是項目中使用了Repository功能,那建議啓動類中指定Repository具體包掃描路徑,以下:架構

@EnableMongoRepositories(basePackages = "xxx.mongo.dao")
@EnableRedisRepositories(basePackages = "xxx.redis.dao")

在這裏插入圖片描述 若是不指定具體Repository掃麪包路徑,那麼不單單會出現本文標題那段提示信息,Repository覆蓋提示信息,以下: 在這裏插入圖片描述app

Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.lucas.device.repository.mongo.DeviceInfoRepository.

消息級別仍然是INFO級別,意思是Redis定義的Repository會跳過DeviceInfoRepository等其餘繼承MongoRepository接口的實例化對象。當咱們定義的Repository接口越多,這種提示信息也就會越多。 在這裏插入圖片描述ide

總結

       雖然只是INFO級別的信息,可是仍是要摸清楚產生的起因,一步步分析下來,咱們更加清楚架構設計不單單是使用,更應該以塑造的目光去精雕細琢,碼農也能夠成功手藝精湛的手藝人。spring-boot

相關文章
相關標籤/搜索