spring boot web项目获取服务器端口号

获取服务器程序监听的端口号,网上的方法都试过,都不管用。联想到eureka 客户端注册的时候需要获取到自己的实例信息,提交到eureka服务器上,eureka client里面肯定有获取端口号的方法。

找源码过程略。

package spring-cloud-netflix-eureka-client/2.0.0.RELEASE/spring-cloud-netflix-eureka-client-2.0.0.RELEASE-sources.jar!/org/springframework/cloud/netflix/eureka/serviceregistry/EurekaAutoServiceRegistration.java

这个包是spring提供的,而不是netflix的eureka-client

// line 119
        @EventListener(WebServerInitializedEvent.class)
    public void onApplicationEvent(WebServerInitializedEvent event) {
        // TODO: take SSL into account
        int localPort = event.getWebServer().getPort();
        if (this.port.get() == 0) {
            log.info("Updating port to " + localPort);
            this.port.compareAndSet(0, localPort);
            start(); // start函数开始注册过程,就是在WebServer完全启动之后才开始执行客户端的注册。
        }
    }

这个方法监听事件WebServerInitializedEvent,然后从对象中获取到了端口号。看看这个类的文档:

Event to be published after the application context is refreshed and the WebServer is ready. Useful for obtaining the local port of a running server.
正好就是用于获取本地端口的事件。

但是这个事件的发布时间一般比创建Bean的时间晚(我测试的都是这样的)。所以使用的时候需要注意,像下面的是有问题的:

// 以下是错误示范!
@Configuration
public class ServiceConfig{
    int port;
    
    // 事件发布之后把端口号保存在成员变量中
    @EventListener(WebServerInitializedEvent.class){
    public void onApplicationEvent(WebServerInitializedEvent event) {
        this.port = event.getWebServer().getPort();
    }

    // 然后创建bean的时候使用这个变量??
    // 想多了,这个bean先创建的,结果是AService使用的port为0
    @Bean
    public AService aService(){
        return new AService(this.port);
    }
}

解决办法挺多的,例如

  1. bean提供setPort方法,事件发布的时候调用set方法。WebServerInitializedEvent有获取ApplicationContext的方法,有了applicationContext就能获取已创建好的某个bean
  2. port定义为引用类型
    ...

猜你喜欢

转载自www.cnblogs.com/gdme1320/p/9543908.html