天天看點

Spring Boot自動化配置的利弊及解決之道

Spring Boot中的雙刃劍:自動化配置

在之前釋出的

Spring Boot基礎教程

系列文章中,我們通過各種功能性示例體驗了Spring Boot的自動化配置給我們所帶來的超便利的新開發方式。但是,在一些情況下Spring Boot的自動化配置也會給我們惹來不少的麻煩,比如這些場景:

  • 項目依賴複雜的情況下,由于依賴方的依賴組織不夠嚴格,可能引入了一些實際我們不需要的依賴,進而導緻我們的項目滿足一些特定的自動化配置。
  • 傳統Spring項目轉換為Spring Boot項目的過程中,由于不同的組織方式問題,引發自動化配置加載的錯誤,比如:通過xml手工組織的多資料源配置等。

上面這些原因都會導緻不必要的自動化配置加載而導緻應用無法啟動或觸發/health的健康檢查不通過等問題。比如,我們在改造傳統Spring項目到Spring Boot項目中碰到的一些錯誤:

六月 21, 2017 6:23:47 下午 org.apache.catalina.loader.WebappClassLoaderBase clearReferencesThreads
警告: The web application [ROOT] appears to have started a thread named [Abandoned connection cleanup thread] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
 java.lang.Object.wait(Native Method)
 java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
 com.mysql.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:43)
2017-06-21 18:23:47,230 INFO  [main] org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer - 

Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2017-06-21 18:23:47,237 ERROR [main] org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter - 

***************************
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).
      

從報錯資訊中,我們就可以分析出錯誤原因是觸發了資料源的自動化配置,然而目前項目其實并不需要資料源。查其根源是依賴方提供的API依賴中引用了一些多餘的依賴觸發了該自動化配置的加載。

https://blog.didispace.com/spring-boot-disable-autoconfig/#%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3 如何解決

為了解決上面所述的問題,我們可以用兩種方法來解決:

  • 通過外部依賴的修改來解決:通過與依賴方溝通,在對方提供的API依賴中去掉不必要的依賴
  • 通過禁用指定的自動化配置來避免加載不必要的自動化配置,下面列舉了禁用的方法:

使用了

@EnableAutoConfiguration

的時候

@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})      

@SpringBootApplication

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})      

@SpringCloudApplication

@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
@SpringCloudApplication      

通過配置檔案來設定

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration