SpringIntegration 和 SpringBoot:选择 Web 服务器以通过依赖包含/排除以外的方式启动



我们在spring-integration中有一个项目,该项目将与webflexservlet实现一起使用,这似乎在使用spring.main.web-application-type属性集作为系统属性时工作得很好。

我现在正在寻找如何在运行时选择嵌入式 Web 服务器。

spring-boot文档说,这是通过pom.xml的依赖项包含或排除来实现的。

https://docs.spring.io/spring-boot/docs/2.1.9.RELEASE/reference/html/howto-embedded-web-servers.html

我正在寻找的是能够从同一个项目/可执行 jar 启动任何jettynettyundertowtomcat

这在SpringApplication中的某些特定启动序列中可行吗?

感谢您的任何指示/建议。

您可以将所有这些作为test范围的依赖项,并使用Spring Boot的FilteredClassLoader来排除当前单元测试中不需要的任何内容:https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.developing-auto-configuration.testing.overriding-classpath。

您可能需要了解 Web 服务器的所有这些自动配置的详细信息,以确定要排除的确切类。

对于当前测试中不需要的特定自动配置,也可以仅使用普通@SpringBootApplication.exclude()(或类似的配置属性)来实现目标。

不过与弹簧集成无关。

我认为我已经找到了一种相对简单和干净的方法来做到这一点。

在创建应用程序上下文时,spring-boot根据属性spring.main.web-application-type中的值,以两种方式之一加载WebServerApplicationContextreactiveservlet(分别为ReactiveWebServerApplicationContextServletWebServerApplicationContext)。

这两个类都有一个方法createWebServer()该方法将查找(分别)ReactiveWebServerFactory或加载到上下文中的ServletWebServerFactory类型的 bean,在这种情况下,该 bean 将是WebApplicationContext使用的WebServerFactory

因此需要将目标WebServerFactory声明为 bean。

有许多不同的方法可以执行此操作,包括使用配置文件。

我选择使用工厂 bean,它将WebServerFactory实例化为系统属性的函数,这里my.main.web-server(作为spring.main.web-application-type的并行)。

使用BeanFactory创建保存WebServerFactory的 bean:

package net.demo;
...
public class MyWebServerFactoryBeanFactory implements EnvironmentAware {
private Environment environment;
public ReactiveWebServerFactory createReactiveWebServerFactory() {
switch(getWebServer()) {
case "jetty":
return new JettyReactiveWebServerFactory();
case "netty":
return new NettyReactiveWebServerFactory();
case "undertow":
return new UndertowReactiveWebServerFactory();
case "tomcat":
case default:
return new TomcatReactiveWebServerFactory();
}
}
public ServletWebServerFactory createServletWebServerFactory() {
switch(getWebServer()) {
case "jetty":
return new JettyServletWebServerFactory();
case "undertow":
return new UndertowServletWebServerFactory();
case "tomcat":
case default:
return new TomcatServletWebServerFactory();
}
}
private String getWebServer() {
return environment.getProperty("my.main.web-server");
}
}

使用 XML 上下文定义,我定义了 BeanFactory 并导入了一个对于reactiveservlet不同的源代码:

...
<import resource="classpath:my-${spring.main.web-application-type:servlet}.xml" />
<bean id="myWebServerFactoryBeanFactory"
class="net.demo.MyWebServerFactoryBeanFactory" />
...

最后,在特定源文件中创建WebServerFactorymy-reactive.xml内:

<bean id="myWebServerFactory" factory-bean="net.demo.MyWebServerFactoryBeanFactory"
factory-method="createReactiveWebServerFactory" />

并在my-servlet.xml内:

<bean id="myWebServerFactory" factory-bean="net.demo.MyWebServerFactoryBeanFactory"
factory-method="createServletWebServerFactory" />

我想您不一定需要专门的导入,因为您可以在上下文中创建ReactiveWebServerFactoryServletWebServerFactory,但只会使用匹配的 bean。

相关内容

  • 没有找到相关文章

最新更新