【问题标题】:Spring annotation conditionalOnBean not workingSpring注释conditionalOnBean不起作用
【发布时间】:2015-10-26 07:14:28
【问题描述】:

我定义了一个带有注解配置的类

    @Configuration
    @AutoConfigureAfter(EndpointAutoConfiguration.class)
    public class EndpointConfiguration {
        @Resource
        private MetricsEndpoint metricsEndpoint;

        @Bean
        public MetricsFormatEndpoint metricsFormatEndpoint() {
            return new MetricsFormatEndpoint(metricsEndpoint);
        }
    }

MetricsFormatEndpoint 运行良好。

但是我使用注解conditionalOnBean,它根本不起作用。

    @Bean
    @ConditionalOnBean(MetricsEndpoint.class)
    public MetricsFormatEndpoint metricsFormatEndpoint() {
        return new MetricsFormatEndpoint(metricsEndpoint);
    }

查看 localhost:8080/beans,spring applicationContext 有 bean 'metricsEndpoint',

    {"bean":"metricsEndpoint","scope":"singleton",
     "type":"org.springframework.boot.actuate.endpoint.MetricsEndpoint",
     "resource":"class path resource 
    [org/springframework/boot/actuate/autoconfigure/EndpointAutoConfiguration.class]",
    "dependencies":[]}

我阅读了注解@ConditionalOnBean 的文档,上面写着应检查的bean 的类类型。当指定的任何类包含在 {@link ApplicationContext} 中时,条件匹配。

谁能告诉我原因

【问题讨论】:

  • 当你说“它根本不起作用”时,会发生什么?您见过哪些失败/意外行为?

标签: spring-boot spring-bean


【解决方案1】:

@ConditionalOnBean 的 javadoc 将其描述为:

Conditional 仅在指定的 bean 类和/或名称已包含在 BeanFactory 中时匹配。

在这种情况下,关键部分是“已经包含在BeanFactory 中”。在任何自动配置类之前考虑您自己的配置类。这意味着在您自己的配置检查其存在时,MetricsEndpoint bean 的自动配置尚未发生,因此,您的 MetricsFormatEndpoint bean 并未创建。

一种方法是为您的MetricsFormatEndpoint bean 使用create your own auto-configuration class 并使用@AutoConfigureAfter(EndpointAutoConfiguration.class) 对其进行注释。这将确保在定义 MetricsEndpoint bean 之后评估其条件。

【讨论】:

  • 我也试试这个,@AutoConfigureAfter(EndpointAutoConfiguration.class),它也不起作用。
  • @AutoConfigureAfter 仅适用于自动配置类。您是否按照我上面的建议创建了自己的?
  • 您能否提供一个具体示例来说明您所描述的内容。我将 FlywayAutoConfiguration 类添加到 spring.factories 中,因此 flyway 迁移在我的配置类之前运行,但当我使用 AutoConfigureAfter 时不会。在我不实际使用 bean 之前,我必须自动装配 FlywayMigrationInitializer 以确保它执行我不喜欢的操作。
  • @AndyWilkinson "在任何自动配置类之前考虑您自己的配置类'。但是,我们怎么可能将启动器 bean 注入应用程序的配置类?
  • @Whimusical 答案是在定义 bean 的上下文中,而不是依赖注入。在定义 bean 时,您自己的配置类会在任何自动配置类之前被考虑。当创建 bean 并注入依赖项时,所有定义的 bean 都被平等地考虑。这允许将来自自动配置的 bean 注入到应用程序自己的 bean 或配置类中。
【解决方案2】:

ConditionalOnClass 也可以。

Javadoc 说 AutoConfigureAfter 应该在其他 specified auto-configuration 类之后应用。

当指定的类在类路径上时,ConditionalOnClass 匹配。我觉得比较合适

【讨论】:

    猜你喜欢
    • 2014-08-14
    • 2016-06-02
    • 1970-01-01
    • 1970-01-01
    • 2021-09-27
    • 2018-03-03
    • 2019-12-07
    • 1970-01-01
    相关资源
    最近更新 更多