2

我正在尝试使用 Spring Boot 自动配置功能并遇到问题。我创建了一个 github 存储库,以便能够轻松地重现“问题”:https ://github.com/clembo590/spring-auto-configuration

只需运行mvn clean install,您将获得我在描述中引用的所有日志。

我已经“启用”了debug=truespring boot 属性以查看是否激活了哪个“自动配置”(如果它不活动,为什么它不活动)。

我还添加了一些日志来“记录所有已添加到 Spring Boot 上下文中的 bean”。

这是我的自动配置类。


@Configuration
@ComponentScan(basePackageClasses = MyClass.class)
@ConditionalOnBean(ObjectMapper.class)
@AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE)
public class CleaningAutoConfiguration {

    @Bean
    public Fake fake(){
        return new Fake();
    }

    private static class Fake{

    }

}

第一个奇怪的事情是这个日志:

   CleaningAutoConfiguration:
      Did not match:
         - @ConditionalOnBean (types: com.fasterxml.jackson.databind.ObjectMapper; SearchStrategy: all) did not find any beans of type com.fasterxml.jackson.databind.ObjectMapper (OnBeanCondition)
      Matched:
         - @ConditionalOnBean (types: com.fasterxml.jackson.databind.ObjectMapper; SearchStrategy: all) found bean 'jacksonObjectMapper' (OnBeanCondition)

第一个问题:为什么 @ConditionalOnBean 既匹配又不匹配?(我对这种情况的期望是它应该匹配或不匹配......但不是两者都......见问题5)

现在,如果我们查看日志,它似乎CleaningAutoConfiguration在该Negative matches:部分中。

第二个问题:为什么CleaningAutoConfiguration自己注册为 bean ?(我期待它不会像本Negative matches节中那样)。

第三个问题:为什么fake仍然注册为bean(我原以为fake不会注册,甚至没有实例化......)

第四个问题:为什么MyClass没有注册为bean?

现在,如果您删除,@ComponentScan(basePackageClasses = MyClass.class)那么所有这些问题都会像CleaningAutoConfiguration进入Positive matches部分一样消失,但会创建一个新问题:

第五个问题:为什么删除 @ComponentScan 会CleaningAutoConfiguration带入Positive matchessection ?(也许问题 5 与问题 1 有某种联系......?)

4

1 回答 1

2

问题的根本原因是在不支持@ComponentScan的自动配置类上使用:

此外,自动配置类不应启用组件扫描以查找其他组件。@Import应该使用特定的 s 来代替。

要回答您的具体问题:

为什么@ConditionalOnBean既匹配又不匹配

它首先被评估为考虑不受支持的@ComponentScan注释的一部分。此时,ObjectMapperbean 尚未定义,因此不匹配。随后在ObjectMapperbean 被定义为匹配点之后对其进行评估。

为什么 CleaningAutoConfiguration 本身注册为 bean ?(我期待它不会像在负匹配部分中那样)。

由于正负匹配,报告在这里误导了您。CleaningAutoConfiguration由于正匹配是一个bean。

为什么fake仍然注册为bean(我原以为fake不会注册,甚至没有实例化......)

报告又误导了你。条件CleaningAutoConfiguration已匹配,因此其Fakebean 已定义。

为什么MyClass没有注册为bean

考虑注释时,条件CleaningAutoConfiguration不匹配,因此未启用 ' 包的组件扫描。@ComponentScanMyClass

为什么删除@ComponentScan带入CleaningAutoConfiguration正匹配部分

它可以防止在尚未定义 beanCleaningAutoConfiguration时过早评估条件。ObjectMapper当它们最终在预期的时间被评估时,ObjectMapperbean 存在并且条件匹配。

于 2022-02-15T21:34:54.410 回答