使用开发项目过程有可能会遇到需要更换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示例工程结构
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
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。