溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Spring?Boot怎么排除自動(dòng)加載數(shù)據(jù)源

發(fā)布時(shí)間:2021-12-17 11:39:24 來(lái)源:億速云 閱讀:350 作者:iii 欄目:開(kāi)發(fā)技術(shù)

本篇內(nèi)容介紹了“Spring Boot怎么排除自動(dòng)加載數(shù)據(jù)源”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

前言

有些老項(xiàng)目使用Spring MVC里面有寫(xiě)好的數(shù)據(jù)庫(kù)連接池,比如redis/mongodb/mybatis(mysql其他Oracle同理)。在這些項(xiàng)目遷入spring boot框架時(shí),會(huì)報(bào)錯(cuò)。

原因是我們業(yè)務(wù)寫(xiě)好了連接池,但spring boot在jar包存在的時(shí)候會(huì)主動(dòng)加載spring boot的autoconfiguration創(chuàng)建連接池,但我們并未配置Spring Boot參數(shù),也不需要配置。

1. mongodb

mongodb自動(dòng)配置錯(cuò)誤如下:

org.mongodb.driver.cluster : Exception in monitor thread while connecting to server localhost:27017
com.mongodb.MongoSocketOpenException: Exception opening socket
Caused by: java.net.ConnectException: Connection refused (Connection refused)

但是我沒(méi)有引入spring-boot-starter-data-mongodb的jar包,后來(lái)發(fā)現(xiàn)我引入了spring-data-mongodb的jar

檢查spring-boot-starter-data-mongodb的jar,包括3部分,如下:

Spring?Boot怎么排除自動(dòng)加載數(shù)據(jù)源

我的jar包都有,相當(dāng)于這些jar拼裝成了 spring-boot-starter-data-mongodb

在Spring Boot中自動(dòng)引入了自動(dòng)配置功能

Spring?Boot怎么排除自動(dòng)加載數(shù)據(jù)源

Spring?Boot怎么排除自動(dòng)加載數(shù)據(jù)源

需要手動(dòng)排除自動(dòng)配置的數(shù)據(jù)源,在SpringBootApplication中exclude

@SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})

啟動(dòng)不再報(bào)錯(cuò)連接localhost:27017,業(yè)務(wù)正常。原理見(jiàn)Spring Boot官方文檔

Spring?Boot怎么排除自動(dòng)加載數(shù)據(jù)源

2. mybatis

mybatis同理

Failed to auto-configure a DataSource: 'spring.datasource.url' is not specified and no embedded data

***************************
APPLICATION FAILED TO START
***************************

Description:

Cannot determine embedded database driver class for database type NONE

Action:

If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).

需要排除

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})

3. 原理講解

原理是EnableAutoConfiguration

Spring?Boot怎么排除自動(dòng)加載數(shù)據(jù)源

進(jìn)一步跟蹤:

Spring?Boot怎么排除自動(dòng)加載數(shù)據(jù)源

AutoConfigurationImportSelector這個(gè)類(lèi)有自動(dòng)加載與排除的邏輯

public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,
annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}

注意加載代碼

getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
/**
	 * Return the {@link AutoConfigurationEntry} based on the {@link AnnotationMetadata}
	 * of the importing {@link Configuration @Configuration} class.
	 * @param autoConfigurationMetadata the auto-configuration metadata
	 * @param annotationMetadata the annotation metadata of the configuration class
	 * @return the auto-configurations that should be imported
	 */
	protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
			AnnotationMetadata annotationMetadata) {
		if (!isEnabled(annotationMetadata)) {
			return EMPTY_ENTRY;
		}
		AnnotationAttributes attributes = getAttributes(annotationMetadata);
		List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
		configurations = removeDuplicates(configurations);
		Set<String> exclusions = getExclusions(annotationMetadata, attributes);
		checkExcludedClasses(configurations, exclusions);
		configurations.removeAll(exclusions);
		configurations = filter(configurations, autoConfigurationMetadata);
		fireAutoConfigurationImportEvents(configurations, exclusions);
		return new AutoConfigurationEntry(configurations, exclusions);
	}

里面

getExclusions(annotationMetadata, attributes);
/**
	 * Return any exclusions that limit the candidate configurations.
	 * @param metadata the source metadata
	 * @param attributes the {@link #getAttributes(AnnotationMetadata) annotation
	 * attributes}
	 * @return exclusions or an empty set
	 */
	protected Set<String> getExclusions(AnnotationMetadata metadata, AnnotationAttributes attributes) {
		Set<String> excluded = new LinkedHashSet<>();
		excluded.addAll(asList(attributes, "exclude"));
		excluded.addAll(Arrays.asList(attributes.getStringArray("excludeName")));
		excluded.addAll(getExcludeAutoConfigurationsProperty());
		return excluded;
	}

看到了,exclude或者excludeName,當(dāng)然還有一種方法

private List<String> getExcludeAutoConfigurationsProperty() {
		if (getEnvironment() instanceof ConfigurableEnvironment) {
			Binder binder = Binder.get(getEnvironment());
			return binder.bind(PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE, String[].class).map(Arrays::asList)
					.orElse(Collections.emptyList());
		}
		String[] excludes = getEnvironment().getProperty(PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE, String[].class);
		return (excludes != null) ? Arrays.asList(excludes) : Collections.emptyList();
	}

通過(guò)application.properties文件配置spring.autoconfigure.exclude

private static final String PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE = "spring.autoconfigure.exclude";

“Spring Boot怎么排除自動(dòng)加載數(shù)據(jù)源”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI