您好,登錄后才能下訂單哦!
SpringBoot項目啟動但沒有監聽端口該怎么辦,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
前提
我們的這個SpringBoot項目依賴Dubbo、RocketMQ、Nacos等,偶爾有一天發現啟動后沒有注冊到SpringBootAdmin里面,于是檢查原因網上搜索資料,找到這篇文章springboot項目正常啟動運行,但端口監聽不到 的事件與解決方案情況類似,我們的項目里面啟動后也在線程里面啟動了死循環,如下:
@PostConstruct public void init() { log.info("==============初始化==============start"); try { //這里有一段代碼在線程里面開啟死循環 xxx.xxx } catch (Exception e) { log.error("", e); } }
參考那個文章說的,可能是還沒等監聽端口然后這邊就一直運行死循環了所以要把這段開啟多線程內死循環的代碼延遲一點啟動,改動如下:
@Slf4j @Component //這里按順序排到第10 @Order(value = 10) public class InitRunner implements ApplicationRunner { @Override public void run() { log.info("==============初始化==============start"); try { //這里有一段代碼在線程里面開啟死循環 xxx.xxx } catch (Exception e) { log.error("", e); } } }
測試啟動,還是不行,看來不是這里的問題。繼續查詢資料看到這篇文章SpringBoot內置Tomcat啟動時間,既然Tomcat沒監聽端口那就調試一下看看程序走到那里就沒去監聽端口了。
調試到關鍵代碼:
class:AbstractApplicationContext @Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }
這里的onRefresh();方法調用了本類里面的onRefresh()方法,看注釋:
/** * Template method which can be overridden to add context-specific refresh work. * Called on initialization of special beans, before instantiation of singletons. * <p>This implementation is empty. * @throws BeansException in case of errors * @see #refresh() */ protected void onRefresh() throws BeansException { // For subclasses: do nothing by default. }
翻譯一下大致意思是:
模板方法,可以重寫該方法以添加特定于上下文的刷新工作。在初始化特殊bean時調用,然后實例化單例。
此實現為空。
看一下這個方法有以下結果實現:
很明顯應該調用ServletWebServerApplicationContext里面的實現,但我下了斷點調試竟然沒有進入到這個方法:
@Override protected void onRefresh() { super.onRefresh(); try { createWebServer(); } catch (Throwable ex) { throw new ApplicationContextException("Unable to start web server", ex); } }
而是直接調了這個空方法:
真神奇。
找了個正常的項目,果然是進入到ServletWebServerApplicationContext里面了。然后了兩個項目的差別,真的是太烏龍了。
我這個項目并沒有依賴spring-boot-starter-web
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency>
加上這一段試試,果然可以了。
2021-04-15 10:33:52.538 [main] INFO [org.springframework.boot.web.embedded.tomcat.TomcatWebServer.start: 204] - Tomcat started on port(s): 8080 (http) with context path '' 2021-04-15 10:33:52.546 [main] INFO [org.springframework.boot.StartupInfoLogger.logStarted: 61] - Started XXXMainApplication in 59.654 seconds (JVM running for 64.354)
可能是當初我考慮到這個項目用Dobbo而不需要spring-web所以就沒依賴。后來添加了SpringBootAdmin監控這個是要項目啟動端口然后SpringBootAdmin去調用接口查詢信息的,然后忘了添加這個依賴。真的是個大烏龍,不過從調試源碼也學到了一些東西,感覺源碼真是個好東西。
關于SpringBoot項目啟動但沒有監聽端口該怎么辦問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。