spring-boot-devtools是個好東西,在開發調試時能夠隨時熱部署,不用每次手工啓停。前兩天一個項目查log,發現總有這樣的錯誤日誌輸出:
java
org.springframework.boot.devtools.restart.SilentExitExceptionHandler$SilentExitExceptionspring at org.springframework.boot.devtools.restart.SilentExitExceptionHandler.exitCurrentThread(SilentExitExceptionHandler.java:90)app at org.springframework.boot.devtools.restart.Restarter.immediateRestart(Restarter.java:184)ide at org.springframework.boot.devtools.restart.Restarter.initialize(Restarter.java:163)spring-boot at org.springframework.boot.devtools.restart.Restarter.initialize(Restarter.java:552)spa at org.springframework.boot.devtools.restart.RestartApplicationListener.onApplicationStartingEvent(RestartApplicationListener.java:67)調試 at org.springframework.boot.devtools.restart.RestartApplicationListener.onApplicationEvent(RestartApplicationListener.java:45)rest at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:167)日誌 at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)開發 at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:122) at org.springframework.boot.context.event.EventPublishingRunListener.starting(EventPublishingRunListener.java:68) at org.springframework.boot.SpringApplicationRunListeners.starting(SpringApplicationRunListeners.java:48) at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) at org.test.Application.main(Application.java:15) |
看一下項目的主體結構,大體是這樣的,我作了簡化:
首先是spring boot的啓動入口:
package org.test; import org.springframework.boot.SpringApplication; import org.springframework.boot.Banner.Mode; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { try { SpringApplication app = new SpringApplication(Application.class); app.setBannerMode(Mode.OFF); app.setWebEnvironment(false); app.run(args); } catch(Exception ex) { ex.printStackTrace(); } } }
主服務大體是這樣的(已簡化):
package org.test; import javax.annotation.PostConstruct; import org.springframework.stereotype.Service; @Service public class MainService { @PostConstruct public void startServer() { System.out.println("START"); } }
只要一啓動,就會報上面的錯誤,但實際上又不影響任何功能,devtools的熱部署功能也仍然生效。對比之前的項目查了查,發現問題出在main()方法上,SpringApplication.run()一但放到try...catch塊裏就會致使devtools拋個異常。把main()裏的try...catch去掉,或者把app.run(args)這句移出try...catch,或者catch到異常不要printStackTrace(),再運行就不會有錯誤日誌了。
具體緣由等有空了再去翻源碼吧,對spring boot來講,啓動時try...catch真的是畫蛇添足。