@EnableWebMvc 上的 Spring 条件 bean

Posted

技术标签:

【中文标题】@EnableWebMvc 上的 Spring 条件 bean【英文标题】:Spring Conditional bean on @EnableWebMvc 【发布时间】:2019-12-11 09:42:48 【问题描述】:

如何根据项目中是否没有另一个用@EnableWebMvc 注释的不同 bean 来控制 bean 的创建?

我试过了

@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)

按照here 的建议,但没有运气。当@EnableWebMvc 存在时,我会得到这种矛盾的状态

WebMvcAutoConfiguration: 不匹配: - @ConditionalOnMissingBean (types: org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; SearchStrategy: all) found beans of type 'org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport' org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration(OnBeanCondition)

还有

ProblemModulesRegisterer 匹配: - @ConditionalOnMissingBean (types: org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; SearchStrategy: all) 没有找到任何bean (OnBeanCondition)

所以它找到并没有找到 WebMvcConfigurationSupport 类型的 bean

作为另一种尝试,我还比较了注册 bean 有和没有 @EnableWebMvc 并注意到没有它,有一个名为 org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration 的 bean。所以我尝试了@ConditionalOnMissingBean(WebMvcAutoConfiguration.class),但它仍然不起作用。它显示了这种矛盾的状态

WebMvcAutoConfiguration 匹配: - @ConditionalOnClass 找到所需的类'javax.servlet.Servlet'、'org.springframework.web.servlet.DispatcherServlet'、'org.springframework.web.servlet.config.annotation.WebMvcConfigurer'(OnClassCondition) - 找到“会话”范围(OnWebApplicationCondition) - @ConditionalOnMissingBean (types: org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; SearchStrategy: all) 没有找到任何bean (OnBeanCondition)

还有

ProblemModulesRegisterer 匹配: - @ConditionalOnMissingBean(类型:org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; SearchStrategy: all)没有找到任何bean(OnBeanCondition)

所以WebMvcAutoConfiguration 匹配(已创建)并且缺少WebMvcAutoConfiguration 的依赖项也匹配

【问题讨论】:

【参考方案1】:

问题是您只能在自动配置上下文中使用@ConditionalOnMissingBean。 javadoc 说

该条件只能匹配到目前为止已由应用程序上下文处理的 bean 定义,因此强烈建议在仅在自动配置类上使用此条件

我试图在常规应用程序中使用注释。有关创建自动配置模块的更多信息,请查看official doc。一旦我这样做了(具体来说,将类添加到spring.factories),它就可以通过使用检测@EnableWebMvc

@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)

【讨论】:

【参考方案2】:

您需要确保 @ConditionalOnMissingBean 带注释的 bean 创建将在 WebMvcConfigurationSupport 创建之后发生。

来自春天docs

当前 bean 所依赖的 bean。指定的任何 bean 都是 保证在这个bean之前由容器创建。

使用@DependsOn 注释除了 @ConditionalOnMissingBean 解释here

并确保您在 @configuration 带注释的类中执行这些操作。

@Configuration
public class Config 

    @Bean
    @DependsOn("webMvcConfigurationSupport")
    @ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
     public FileProcessor fileProcessor()
        return new FileProcessor();
    

在本例中,仅当缺少 webMvcConfigurationSupport bean 时才会创建 fileProcessor。

【讨论】:

这不起作用。它在启动时提供A component required a bean named 'webMvcConfigurationSupport' that could not be found.。而且我不知道实际 bean 的名称。这就是为什么我试图根据注释@EnableWebMvc` 为什么要避免使用这个 bean?【参考方案3】:

@ConditionalOnMissingBean 将执行您的代码,而您想要的是相反的 - 执行。也许您应该尝试在您发布的链接中的示例中提供@ConditionalOnClass@AutoConfigureAfter 的混合使用。

我在少数与数据库相关的 bean 中使用过,并且对 Conditionals 和 AutoconfigureAfter 的操作实际上可以解决问题。只需要更好地了解您的应用程序,就能提供更具体的建议

【讨论】:

@conditional 以什么类为条件?我需要的是任何类,只要它带有@EnableWebMvc 注释。 configureAfter 的问题相同。之后是什么?目标是拥有一个通用的 Spring 解决方案,而不是仅限于我当前的 @EnableWebMvc 实现 Configuration。单点提取您需要的逻辑并有条件地处理它。仅在存在方面的情况下才允许执行

以上是关于@EnableWebMvc 上的 Spring 条件 bean的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 不使用配置的 Jackson ObjectMapper 和 @EnableWebMvc

无法使用 @EnableWebMvc 配置运行 SPRING BOOT 应用程序

在spring boot中使用@EnableWebMvc 一定要注意的问题!

springmvc enablewebmvc注解作用

当我没有使用该注释或任何与 MVC 相关的依赖项时,Spring 会抱怨 @EnableWebMvc

spring mvc之注解@EnableWebMvc