【问题标题】:How to get the SPRING Boot HOST and PORT address during run time?如何在运行时获取 SPRING Boot HOST 和 PORT 地址?
【发布时间】:2016-12-19 08:44:54
【问题描述】:

如何在运行时获取部署应用程序的主机和端口,以便在我的 java 方法中使用它?

【问题讨论】:

标签: spring-boot port host


【解决方案1】:

您可以通过Environment 获取此信息,对于porthost 您可以使用InternetAddress 获取。

@Autowired
Environment environment;

// Port via annotation
@Value("${server.port}")
int aPort;

......
public void somePlaceInTheCode() {
    // Port
    environment.getProperty("server.port");
    
    // Local address
    InetAddress.getLocalHost().getHostAddress();
    InetAddress.getLocalHost().getHostName();
    
    // Remote address
    InetAddress.getLoopbackAddress().getHostAddress();
    InetAddress.getLoopbackAddress().getHostName();
}

【讨论】:

  • 只有在以下情况下才能以这种方式获取端口:a) 端口实际上是显式配置的,并且 b) 它没有设置为 0(意味着 servlet 容器将在启动时选择一个随机端口)。要获取实际端口,需要实现ApplicationListener<EmbeddedServletContainerInitializedEvent>,并从提供的事件中获取端口。
  • 在使用随机端口的情况下,使用local.server.port而不是server.port会是更好的选择(server.port=0)。
  • 环回地址(127.0.0.1)是远程地址吗?
  • “本地地址”和“远程地址”地址有什么区别?
【解决方案2】:

如果你使用像server.port=${random.int[10000,20000]}这样的随机端口方法。并在 Java 代码中读取Environment 中的端口,使用@ValuegetProperty("server.port")你会得到一个不可预测的端口,因为它是随机的。

ApplicationListener,你可以重写 onApplicationEvent 来获取设置后的端口号。

在 Spring boot 版本中实现 Spring 接口 ApplicationListener<EmbeddedServletContainerInitializedEvent>(Spring boot 版本 1) 或 ApplicationListener<WebServerInitializedEvent>(Spring boot 版本 2) 覆盖 onApplicationEvent 以获取 Fact Port。

弹簧靴1

@Override
public void onApplicationEvent(EmbeddedServletContainerInitializedEvent event) {
    int port = event.getEmbeddedServletContainer().getPort();
}

弹簧靴2

@Override
public void onApplicationEvent(WebServerInitializedEvent event) {
    Integer port = event.getWebServer().getPort();
    this.port = port;
}

【讨论】:

    【解决方案3】:

    这是一个 util 组件:

    EnvUtil.java
    (放入适当的包中,成为一个组件。)

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.core.env.Environment;
    import org.springframework.stereotype.Component;
    
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    
    /**
     * Environment util.
     */
    @Component
    public class EnvUtil {
        @Autowired
        Environment environment;
    
        private String port;
        private String hostname;
    
        /**
         * Get port.
         *
         * @return
         */
        public String getPort() {
            if (port == null) port = environment.getProperty("local.server.port");
            return port;
        }
    
        /**
         * Get port, as Integer.
         *
         * @return
         */
        public Integer getPortAsInt() {
            return Integer.valueOf(getPort());
        }
    
        /**
         * Get hostname.
         *
         * @return
         */
        public String getHostname() throws UnknownHostException {
            // TODO ... would this cache cause issue, when network env change ???
            if (hostname == null) hostname = InetAddress.getLocalHost().getHostAddress();
            return hostname;
        }
    
        public String getServerUrlPrefi() throws UnknownHostException {
            return "http://" + getHostname() + ":" + getPort();
        }
    }
    

    示例 - 使用 util:

    然后可以注入 util,并调用它的方法。
    这是控制器中的一个示例:

    // inject it,
    @Autowired
    private EnvUtil envUtil;
    
    /**
     * env
     *
     * @return
     */
    @GetMapping(path = "/env")
    @ResponseBody
    public Object env() throws UnknownHostException {
        Map<String, Object> map = new HashMap<>();
        map.put("port", envUtil.getPort());
        map.put("host", envUtil.getHostname());
        return map;
    }
    

    【讨论】:

      【解决方案4】:

      对于主机: 正如安东所提到的

      // Local address
      InetAddress.getLocalHost().getHostAddress();
      InetAddress.getLocalHost().getHostName();
      
      // Remote address
      InetAddress.getLoopbackAddress().getHostAddress();
      InetAddress.getLoopbackAddress().getHostName();
      

      端口: 正如 Nicolai 所提到的,只有在显式配置且未设置为 0 的情况下,您才能通过 environment 属性检索此信息。

      有关该主题的 Spring 文档: https://docs.spring.io/spring-boot/docs/current/reference/html/howto-embedded-servlet-containers.html#howto-discover-the-http-port-at-runtime

      对于执行此操作的实际方法,此处已回答: Spring Boot - How to get the running port

      这里有一个关于如何实现它的 github 示例: https://github.com/hosuaby/example-restful-project/blob/master/src/main/java/io/hosuaby/restful/PortHolder.java

      【讨论】:

        【解决方案5】:

        上面的答案只是一个完整的例子

        package bj;
        
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.boot.SpringApplication;
        import org.springframework.boot.autoconfigure.SpringBootApplication;
        import org.springframework.boot.context.event.ApplicationReadyEvent;
        import org.springframework.context.ApplicationContext;
        import org.springframework.context.ApplicationListener;
        import org.springframework.core.env.Environment;
        
        import java.net.InetAddress;
        import java.net.UnknownHostException;
        
        @SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
        @SpringBootApplication
        class App implements ApplicationListener<ApplicationReadyEvent> {
        
            @Autowired
            private ApplicationContext applicationContext;
        
            public static void main(String[] args) {
                SpringApplication.run(App.class, args);
            }
        
            @Override
            public void onApplicationEvent(ApplicationReadyEvent event) {
                try {
                    String ip = InetAddress.getLocalHost().getHostAddress();
                    int port = applicationContext.getBean(Environment.class).getProperty("server.port", Integer.class, 8080);
                    System.out.printf("%s:%d", ip, port);
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
            }
        }
        

        【讨论】:

          【解决方案6】:

          在运行时绑定的端口可以被注入为:

          @Value('${local.server.port}')
          private int port;
          

          【讨论】:

            猜你喜欢
            • 2019-01-08
            • 2018-08-09
            • 1970-01-01
            • 1970-01-01
            • 2021-09-28
            • 2015-07-30
            • 2020-03-17
            • 1970-01-01
            • 2020-06-29
            相关资源
            最近更新 更多