使用开发项目过程有可能会遇到需要更换web服务器的需求,默认内置的web服务器为,现在搜到的文章都是通过排除法进行实现的,以切换为jetty为例,也就是下面这样

排除法


       
       
            org.springframework.boot
            spring-boot-starter-web
           
           
               
                    spring-boot-starter-tomcat
                    org.springframework.boot
               
           
       
       
       
            org.springframework.boot
            spring-boot-starter-jetty
       
   

通过排除默认的, 然后再加入新的jetty依赖,这样做虽然能实现,但是每次切换需要重新打包部署web服务器配置,有没有一种方式可以实现通过配置文件进行动态切换,而不用重新进行打包部署。

答案是可以的。

动态切换实现方案

经过分析源码,并验证web服务器配置,最终实现了动态切换效果,整体实现思路为

1. 首先排除默认加载web服务器的配置类

2. 在配置文件自定义配置用于切换web服务器的属性,如 .type

3. 分别定义各个web服务器的自定义ory,并结合y通过上面的.type属性值进行动态控制该工厂类Bean的加载

4. 经过以上过程,就可以实现web服务器的动态控制

Demo示例工程结构

配置web服务器步骤_配置web服务器需要注意什么_web服务器配置

POM定义


<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    4.0.0

    io.web
    web-server-demo
    1.0-SNAPSHOT

   
       
            org.springframework.boot
            spring-boot-starter-web
            2.7.8
       

       
            org.springframework.boot
            spring-boot-starter-jetty
            2.7.8
       

       
            org.springframework.boot
            spring-boot-starter-undertow
            2.7.8
       

   

   
       
           
                org.apache.maven.plugins
                maven-compiler-plugin
                3.11.0
               
                    8
                    8
                    UTF-8
               
           
       
   

.yaml

server:
  port: 9090
  type: undertow # 控制切换

spring:
  autoconfigure:
    exclude:
      - org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration

自定义配置

package io.web.embed.tomcat;

import org.apache.catalina.connector.Connector;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

@Configuration
@ConditionalOnProperty(name = "server.type", havingValue = "tomcat")
public class TomcatConfiguration {

    @Autowired
    private Environment environment;

    @Bean
    TomcatServletWebServerFactory tomcatServletWebServerFactory(){
        TomcatServletWebServerFactory webServerFactory = new TomcatServletWebServerFactory();
        webServerFactory.addErrorPages(new ErrorPage("/error"));
        webServerFactory.addConnectorCustomizers(new TomcatConnectorCustomizer() {

            public void customize(Connector conn) {
                int port = environment.getProperty("server.port",Integer.class,8080);
                conn.setPort(port);

                // todo 其他自定义配置
            }
        });

        return webServerFactory;
    }

}

Jetty自定义配置

package io.web.embed.jetty;

import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer;
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

@Configuration
@ConditionalOnProperty(name = "server.type", havingValue = "jetty")
public class JettyConfiguration {

    @Autowired
    private Environment environment;

    @Bean
    ServletWebServerFactory jettyServletWebServerFactory(){
        JettyServletWebServerFactory jettyServletWebServerFactory = new JettyServletWebServerFactory();
        jettyServletWebServerFactory.addErrorPages(new ErrorPage("/error"));
        jettyServletWebServerFactory.addServerCustomizers(new JettyServerCustomizer() {

            public void customize(Server server) {
                ServerConnector httpConnector = new ServerConnector(server);

                int port = environment.getProperty("server.port",Integer.class,8080);
                httpConnector.setPort(port);
                // todo 其他自定义配置

                server.setConnectors(new Connector[] {httpConnector});
            }
        });
        return jettyServletWebServerFactory;
    }

}

自定义配置

package io.web.embed.undertow;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

@Configuration
@ConditionalOnProperty(name = "server.type", havingValue = "undertow")
public class UndertowConfiguration {

    @Autowired
    private Environment environment;

    @Bean
    UndertowServletWebServerFactory undertowServletWebServerFactory(){
        int port = environment.getProperty("server.port",Integer.class,8080);
        UndertowServletWebServerFactory webServerFactory = new UndertowServletWebServerFactory(port);
        webServerFactory.addErrorPages(new ErrorPage("/error"));

        // todo 其他自定义配置
        return webServerFactory;
    }

}

测试接口

package io.web.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {

    @Autowired
    private Environment environment;

    @RequestMapping("/")
    public String hello(){
        return "hello " + environment.getProperty("server.type");
    }

}

演示效果

修改配置文件 .type 为, 启动服务器

服务已切换为

打开浏览器访问,查看切换成功。

·······END·······


限时特惠:
本站持续每日更新海量各大内部创业课程,一年会员仅需要98元,全站资源免费下载
点击查看详情

站长微信:Jiucxh

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注