Spring Boot 不同启动方式(内置和外置 Tomcat 启动)对应获取端口方式

spring boot 可以打包成可执行jar运行(内置Tomcat),也可以打包成war包,放到tomcat的webapp文件夹下进行运行发布(外置Tomcat);根据运行的方式的不同,获取端口的方式也有差别(不是获取配置文件中配置的端口,而且Tomcat也不是根据 spring boot 的配置文件设置端口发布项目)

内置Tomcat获取端口方式:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext;
import org.springframework.context.annotation.Configuration;

/**
 * @author
 * @date 2024/1/26 17:56
 */
@Configuration
public class TTConfig {
    @Autowired
    private ServletWebServerApplicationContext appContext;
    public int getPort(){
        return appContext.getWebServer().getPort();
    }
}

外置Tomcat获取端口方式:


import javax.management.*;
import java.lang.management.ManagementFactory;
import java.util.Set;

/**
 * @author 
 * @date 2024/1/26 17:55
 */
public class TTUtil {
    /**
     * 获取外置 tomcat 启动的 http 开放端口
     * 参考:https://blog.csdn.net/oNew_Lifeo/article/details/127276152
     * @return
     */
    private int getTomcatPort() {
        MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();
        try {
            QueryExp protocol = Query.match(Query.attr("protocol"), Query.value("HTTP/1.1"));
            ObjectName name = new ObjectName("*:type=Connector,*");
            Set<ObjectName> objectNames = beanServer.queryNames(name, protocol);
            for (ObjectName objectName : objectNames) {
                String catalina = objectName.getDomain();
                if ("Catalina".equals(catalina)) {
                    return Integer.parseInt(objectName.getKeyProperty("port"));
                }
            }
        } catch (MalformedObjectNameException e) {
            e.printStackTrace();
        }
        return 0;
    }
}

出现这种情况的原因:

这里涉及 spring boot 启动加载Tomcat容器的机制,tomcat外置启动项目时,容器中的 webServer为空,内置tomcat启动webServer这个有值;

具体可以用IDEA对下方方法加断点,debug启动可以观察到 内置tomcat启动时 servletContext 为空,外置tomcat启动时servletContext 不为空;

关键代码:org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext#createWebServer


	@Override
	protected void onRefresh() {
		super.onRefresh();
		try {
			createWebServer();
		}
		catch (Throwable ex) {
			throw new ApplicationContextException("Unable to start web server", ex);
		}
	}
	private void createWebServer() {
		WebServer webServer = this.webServer;
		ServletContext servletContext = getServletContext();
		if (webServer == null && servletContext == null) {
			StartupStep createWebServer = this.getApplicationStartup().start("spring.boot.webserver.create");
			ServletWebServerFactory factory = getWebServerFactory();
			createWebServer.tag("factory", factory.getClass().toString());
			this.webServer = factory.getWebServer(getSelfInitializer());
			createWebServer.end();
			getBeanFactory().registerSingleton("webServerGracefulShutdown",
					new WebServerGracefulShutdownLifecycle(this.webServer));
			getBeanFactory().registerSingleton("webServerStartStop",
					new WebServerStartStopLifecycle(this, this.webServer));
		}
		else if (servletContext != null) {
			try {
				getSelfInitializer().onStartup(servletContext);
			}
			catch (ServletException ex) {
				throw new ApplicationContextException("Cannot initialize servlet context", ex);
			}
		}
		initPropertySources();
	}

参考

1.SpringBoot获取项目ip和端口号【内置和外置获取的两种方式】
2.spring boot启动加载tomcat原理深度剖析

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值