springboot启动太慢优化
需求緣起:有人在【springboot】微信公眾號問:springboot啟動慢的問題何時有個分享就好了,謝謝。粉絲的問題還是要認真的回答的。
?
???????我們先看看本節(jié)的大綱:
(1)組件自動掃描帶來的問題(@SpringBootApplication);(2)如何避免組件自動掃描帶來的問題(不使用@ SpringBootApplication);
(3)引發(fā)的問題——無法掃描組件;
(4)千古紅樓只一夢,竹籃打水一場空;
(5)debug debug,bug bug更健康;
(6)分析Positive matches和Negative matches;
(7)再次優(yōu)化配置信息;
(8)總結(jié)
?
接下來我們一起探討下每個問題。
(1)組件自動掃描帶來的問題(@SpringBootApplication);
???????我們在第一篇博客就介紹了,我們默認情況下,我們會使用@SpringBootApplication注解來自動獲取應(yīng)用的配置信息,但這樣也會帶來一些副作用。使用這個注解后,會觸發(fā)自動配置(auto-configuration)和組件掃描(component scanning),這跟使用@Configuration、@EnableAutoConfiguration和@ComponentScan三個注解的作用是一樣的。這樣做給開發(fā)帶來方便的同時,會有以下的一些影響:
(a)會導(dǎo)致項目啟動時間變長(原因:加載了我們不需要使用的組件,浪費了cpu資源和內(nèi)存資源)。當(dāng)啟動一個大的應(yīng)用程序,或?qū)⒆龃罅康募蓽y試啟動應(yīng)用程序時,影響會特別明顯。
(b)會加載一些不需要的多余的實例(beans)。
(c)會增加CPU消耗和內(nèi)存的占用。
?
(2)如何避免組件自動掃描帶來的問題(不使用@ SpringBootApplication);
???????本著有問題就要解決的心態(tài),針對以上的問題,我們要怎么解決呢?很明顯,既然@SpringBootApplication加載了一些不必要的配置,那么我們想是否可以就加載我們自己指定的配置呢?我們的思路不使用@SpringBootApplication,并且不使用@ComponentScan注解(此注解會自動掃描我們注解了@Controller,@Service的注解的類,加載到Spring IOC容器中),然后我們使用@Configuration和@EnableAutoConfiguration進行配置啟動類,代碼如下:
package?com.kfit.spring_boot_performance;
?
import?org.springframework.boot.SpringApplication;
import?org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import?org.springframework.context.annotation.Bean;
import?org.springframework.context.annotation.Configuration;
?
import?com.kfit.spring_boot_performance.controller.HelloController;
?
/**
?*?@author?Angel?--守護天使
?*?@version?v.0.1
?*?@date?2017年3月11日
?*/
//移除?@SpringBootApplication and @ComponentScan,?用?@EnableAutoConfiguration?來替代
@Configuration
@EnableAutoConfiguration
public?class?App {
???
???
????public?static?void?main(String[]?args) {
?????? SpringApplication.run(App.class,?args);
??? }
}
?
(3)引發(fā)的問題——無法掃描組件;
我們正要為我們的代碼改良慶幸的時候,我們發(fā)現(xiàn)問題來了。啟動之后,訪問我們編寫的訪問頁面/index,出現(xiàn)錯誤:There was an unexpected error (type=Not Found, status=404).
這是由于什么引起的呢?還記得我們剛剛介紹的@ComponentScan注解嘛,啟用這個注解Spring才能夠進行自動組件的掃描,否則無法掃描到我們編寫的組件類。那么問題來了,怎么辦呢?問題的解決就是:顯式進行配置。
???????注入代碼如下(假設(shè)我們寫的類是HelloController,在這里博主直接寫在App.java啟動類進行注入):
???@Bean
????public?HelloController helloController(){
?????? ?return?new?HelloController();
??? }
在以上的代碼中用?@Bean?注解明確顯式配置,以便被?Spring?掃描到。
在重新啟動之后,我們就可以正常訪問/index頁面了。
???????到這里肯定就會有人會說:那這樣的話,不是會增加我們的編碼量。我只能說:你既要加載快,又要不編碼,博主實在不知道怎么辦了。凡事有利有弊,自己權(quán)衡利弊。
?
(4)千古紅樓只一夢,竹籃打水一場空
???????有人不相信,這個真的能啟動更快嗎,于是乎就編碼進行測試。哈哈,露餡了,還是一樣啟動的跟蝸牛一樣慢。那為什么是這樣呢?為什么我們研究了半天,最終卻是:千古紅樓只一夢,竹籃打水一場空。
???????聰明的讀者,會注意到我們提到:@SpringBootApplication注解的作用跟@EnableAutoConfiguration注解的作用是相當(dāng)?shù)?#xff0c;那就意味著它也能帶來上述的問題。要避免這些問題,我們就要知道我們的組件列表是哪些?
?
(5)debug debug,bug bug更健康
???????我們在上面說了,我們的問題就是如何知道我們的組件列表是哪些?這時候debug就隆重登場了,鼓掌歡迎debug先生上場。
?
???????請問debug先生:在此時此刻您有什么獲獎感言?
?????? debug先生:經(jīng)歷了慢慢人生,我終于發(fā)現(xiàn)我的價值了。在這里我要感謝CCTV、感謝MTV、感謝可口可樂,感謝非常可樂、感謝加多寶、感謝王老吉、感謝主辦方SpringBoot,讓我有機會在這個舞臺跟大家見面。謝謝你們,我一定不會讓大家失望的。
?
???????好了,廢話不多說了,我們先看看如何使用debug呢?
第一種情況:使用spring-boot:run啟動方式
???????這種情況的話,完整的運行代碼是:
???????spring-boot:run -Ddebug
?
第二種情況:使用Run As?——?Java Application啟動方式
???????這種情況的話,配置VM參數(shù)即可,具體操作如下:
【右鍵】——【Run As】——【Run? Configurations…】——【選擇Arguments】——【VM arguments】中加入:【-Ddebug】。
?
這時候在啟動的時候,我們就能看到控制臺打印出了一些我們平時沒看到過的日志信息。
=========================AUTO-CONFIGURATION REPORT
=========================
Positive matches:
-----------------
DispatcherServletAutoConfiguration matched
- @ConditionalOnClass found required class 'org.springframework.web.servlet.DispatcherServlet' (OnClassCondition)
- @ConditionalOnWebApplication (required) found StandardServletEnvironment (OnWebApplicationCondition)
//此處省略剩下的打印信息…
?
?
(6)?????分析Positive matches和Negative matches;
???????在打印信息里,我們有必要先了解下這里的一些知識:
(a)?Positive match:累出匹配到對應(yīng)類的配置項。(b)?Negative match:不包括某個配置項的原因。
?
現(xiàn)在以DataSourceAutoConfiguration舉例說明:
(a)@ConditionalOnClass表示對應(yīng)的類在classpath目錄下存在時,才會去解析對應(yīng)的配置文件,對于DataSourceAutoConfiguration來說就是指:只有javax.sql.DataSource和org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType類都存在時,就會配置對應(yīng)的數(shù)據(jù)庫資源。(b)@ConditionalOnMissingClass表示對應(yīng)的類在classpath目錄下找不到。
(c)OnClassCondition用于表示匹配的類型(postive or negative)。
OnClassCondition是最普遍的瀏覽探測條件,除此之外,Spring Boot也使用別的探測條件,如:OnBeanCondition用于檢測指定bean實例存在與否、OnPropertyCondition用于檢查指定屬性是否存在等等。
符合negative match代表一些配置類(xxxConfiguration之類的),它們雖然存在于classpath目錄,但是修飾它們的注解中依賴的其他類不存在。
?
?
(7)?????再次優(yōu)化配置信息
???????根據(jù)上面的理論知識,我們只需要在啟動的時候,顯式地引入這些組件,拷貝Positive matches中列出的信息:
DispatcherServletAutoConfiguration?
EmbeddedServletContainerAutoConfiguration?
ErrorMvcAutoConfiguration?
HttpEncodingAutoConfiguration?
HttpMessageConvertersAutoConfiguration?
JacksonAutoConfiguration?
JmxAutoConfiguration?
MultipartAutoConfiguration?
ServerPropertiesAutoConfiguration?
PropertyPlaceholderAutoConfiguration?
ThymeleafAutoConfiguration?
WebMvcAutoConfiguration?
WebSocketAutoConfiguration
?
然后來更新項目配置,顯式地引入這些組件,引入之后,再運行一下應(yīng)用確保沒有錯誤發(fā)生:
@Configuration
@Import({
??????? DispatcherServletAutoConfiguration.class,
??????? EmbeddedServletContainerAutoConfiguration.class,
??????? ErrorMvcAutoConfiguration.class,
??????? HttpEncodingAutoConfiguration.class,
??????? HttpMessageConvertersAutoConfiguration.class,
??????? JacksonAutoConfiguration.class,
??????? JmxAutoConfiguration.class,
??????? MultipartAutoConfiguration.class,
??????? ServerPropertiesAutoConfiguration.class,
??????? PropertyPlaceholderAutoConfiguration.class,
??????? ThymeleafAutoConfiguration.class,
??????? WebMvcAutoConfiguration.class,
??????? WebSocketAutoConfiguration.class,
})
public class App {
?
???????在上面的代碼中,我們可以刪掉我們不需要的組件信息,來挺高應(yīng)用的性能,比如在項目中沒有使用Jmx和WebSocket功能的話,那么我們就可以刪除JmxAutoConfiguration.class和WebSocketAutoConfiguration.class。
刪除掉之后,再次運行項目,確保一切正常。
?
(8)總結(jié)
???????在本篇文章中我們介紹了如何加速spring boot快速啟動,主要的思路就是廢棄@SpringBootApplication顯式的引入我們所需要的組件。
???????下節(jié)預(yù)告:介紹高性能Web服務(wù)器Undertow,在下一篇介紹如何替換Tomcat使用Undertow進行內(nèi)存優(yōu)化。
轉(zhuǎn)載于:https://www.cnblogs.com/cmfwm/p/7943756.html
總結(jié)
以上是生活随笔為你收集整理的springboot启动太慢优化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQL-ALTER-change和mod
- 下一篇: 适合win7的python版本_Pyth