Java @同一类型上的ConditionalOnMissingBean和@ConditionalOnBean

Java @同一类型上的ConditionalOnMissingBean和@ConditionalOnBean,java,spring,spring-boot,Java,Spring,Spring Boot,我遇到了奇怪的情况。我正试图编写一个自动配置类,在这个类中,如果另一个bean存在或不存在,我将创建bean,所以我对bean设置了条件,并对同一类型上缺少的bean设置了条件 这是我的密码: @Bean @ConditionalOnMissingBean( type = {"com.example.Api"} ) public ApiManager apiManager() { return new ApiManager() { public Result ge

我遇到了奇怪的情况。我正试图编写一个自动配置类,在这个类中,如果另一个bean存在或不存在,我将创建bean,所以我对bean设置了条件,并对同一类型上缺少的bean设置了条件

这是我的密码:

@Bean
@ConditionalOnMissingBean(
    type = {"com.example.Api"}
)
public ApiManager apiManager() {
    return new ApiManager() {
        public Result getValue(Request request) {
            throw new Exception("Api not provided.");
        }

        public Result setValue(Request request) {
            throw new Exception("Api not provided.");
        }
    };
}

@Bean
@ConditionalOnBean(
    type = {"com.example.Api"}
)
public ApiManager apiManager(Api api) {
    return new ApiManagerImpl(api);
}
问题是,如果它已经签入
@conditionalnmissingbean
类型为
com.example.Api
的bean,那么它不会检查
@conditionalnommissingbean
,并且没有创建bean

我得到的错误如下:

Parameter 2 of constructor in com.example.ServiceImpl required a bean of type 'com.example.ApiManager' that could not be found.
- Bean method 'apiManager' in 'ApiAutoConfiguration' not loaded because @ConditionalOnMissingBean (types: com.example.Api; SearchStrategy: all) found bean 'api'
- Bean method 'apiManager' in 'ApiAutoConfiguration' not loaded because @ConditionalOnMissingBean (types: com.example.Api; SearchStrategy: all) found bean 'api'

你得到的是很合乎逻辑的。按顺序评估条件,这就是为什么在用户配置之后处理自动配置

如果上下文符合您的期望,那么在执行任何操作之前,我们必须评估所有bean定义的所有条件。这将使自动配置无法处理用户(用户配置)或自动配置提供的特定类型的bean这一事实

您需要重写此自动配置以按顺序导入内容。一种方法是移动包私有配置类上的每个方法,然后执行以下操作:

@Configuration
@Import({ApiPresentConfiguration.class, ApiNotPresentConfiguration.class})
处理此问题的更好方法实际上是根本不这样做,只需使用
ObjectProvider

@Bean
public ApiManager apiManager(ObjectProvider<Api> api) {
    // Check if API is present and then return the appropriate implementation
}
@Bean
公共api管理器api管理器(ObjectProvider api){
//检查API是否存在,然后返回相应的实现
}

我希望它能与
ObjectProvider一起工作
但仍然不能使用条件。。。当与
@Import
一起使用时,我应该在
ApiPresentConfiguration
条件中使用吗?导入只是按照您希望的方式计算条件。使用Import时,它会进入
APIPNotPresentConfiguration
,但是
Api
bean是由另一个
自动配置创建的,因此顺序是错误的是吗?
Api
自动配置
应在
apimengager自动配置之前执行
是吗?