如何禁用 TomcatServletWebServerFactory 的 SpringBoot 自动配置以便自定义 spring-starter 提供它?

Posted

技术标签:

【中文标题】如何禁用 TomcatServletWebServerFactory 的 SpringBoot 自动配置以便自定义 spring-starter 提供它?【英文标题】:How to disable SpringBoot autoconfiguration for TomcatServletWebServerFactory in order for a custom spring-starter to provide it? 【发布时间】:2020-03-08 07:46:49 【问题描述】:

所以我正在编写自己的 SpringBootStarter,它应该能够在 SpringBoot 应用程序的嵌入式 tomcat 中启用 JNDI 查找。

我的示例 SpringBoot 应用程序依赖于我的自定义 SpringBootStarter,而后者又依赖于 spring-boot-starter-web。如果我在示例 SpringBoot 应用程序中创建如下配置类,则一切正常:

@Configuration
public class SampleSpringBootAppConfig 


@Bean
public TomcatServletWebServerFactory tomcatFactory() 
    return new TomcatServletWebServerFactory() 
        @Override
        protected TomcatWebServer getTomcatWebServer(org.apache.catalina.startup.Tomcat tomcat) 
            System.out.println("CONFIGURING CUSTOM TOMCAT WEB SERVER FACTORY ");
            tomcat.enableNaming();
            return super.getTomcatWebServer(tomcat);
        

        @Override
        protected void postProcessContext(Context context) 



            ContextResource resource = new ContextResource();
            resource.setName("myDataSource");
            resource.setType(DataSource.class.getName());
            resource.setProperty("driverClassName", "org.postgresql.Driver");

            resource.setProperty("url", "jdbc:postgresql://localhost:5432/postgres");
            resource.setProperty("username", "postgres");
            resource.setProperty("password", "postgres");

            context.getNamingResources()
                    .addResource(resource);

        
    ;

因为 SpringBoot 找到了一个自定义 Bean,所以不会有一个自动配置的默认 Bean/它被覆盖并且 JNDI 已成功启用。

但是,一旦我将此 Bean 配置提取到我的自定义 SpringBoot Starter 的自动配置模块中,尝试启动示例 SpringBoot 应用程序时会引发以下异常:

org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to multiple ServletWebServerFactory beans : tomcatServletWebServerFactory,tomcatFactory

我认为这是由于 SpringBoot 没有找到自定义的 Bean,因此创建了一个自动配置的默认 Bean,它也不会被覆盖。所以现在会有两个 ServletWebServerFactory bean,一个是默认的,一个来自我的自动配置模块。

到目前为止我尝试了什么(无济于事):

使用 @Primary 注释我的自定义 Bean 将 spring.main.allow-bean-definition-overriding 设置为 true

有没有办法让 SpringBoot 不初始化自动配置的默认 bean,或者任何其他可能的解决方案?

【问题讨论】:

【参考方案1】:

试试这个 @AutoConfigureBefore(ServletWebServerFactoryAutoConfiguration.class)

【讨论】:

【参考方案2】:

我能够通过排除负责的 AutoConfiguration 类自己解决这个问题:

@SpringBootApplication ( exclude = ServletWebServerFactoryAutoConfiguration.class)

【讨论】:

以上是关于如何禁用 TomcatServletWebServerFactory 的 SpringBoot 自动配置以便自定义 spring-starter 提供它?的主要内容,如果未能解决你的问题,请参考以下文章

如何禁用 UIButton 和禁用 touchEvent 响应程序?

如何禁用ECSHOP缓存,如何关闭ECSHOP缓存

表单提交后如何禁用以前禁用的选择

LINUX7如何彻底禁用ipv6和如何临时禁用

如何在 DataGridView 中禁用排序?

如何禁用键盘某个键?