@ConditionalOnMissingBean 生效条件 简单印证

 

在学习SpringBoot时,遇到@EnableWebMvc注解:

(1)EnableWebMvc的核心,引入了DelegatingWebMvcConfiguration实例;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}

(2)而 DelegatingWebMvcConfiguration 继承 WebMvcConfigurationSupport

@Configuration(proxyBeanMethods = false)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {

(3)在SpringBoot的WebMvc自动配置类中 WebMvcAutoConfiguration ,有注解 @ConditionalOnMissingBean(WebMvcConfigurationSupport.class),即当 WebMvcConfigurationSupport 存在时,WebMvcAutoConfiguration不生效


@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class) //容器中没有这个组件的时候,这个自动配置类才生效
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
        ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {

 

产生疑问:

@EnableWebMvc 注解引入的是 DelegatingWebMvcConfiguration 实例,

而 @ConditionalOnMissingBean 参数是 WebMvcConfigurationSupport 类(DelegatingWebMvcConfiguration 的父类),

猜想:

是否即 @ConditionalOnMissingBean 会识别到 WebMvcConfigurationSupport 的继承树,容器中存在 WebMvcConfigurationSupport 的子类,@ConditionalOnMissingBean 也返回 false,使得该自动配置类也不生效?

 

进行验证:

@SpringBootTest
public class ConditionalOnMissingBeanTests {

    //获取notebookPC实例
    @Qualifier("notebookPC")
    @Autowired(required = false)
    Computer notebookPC;
    
    //获取reservePC实例
    @Qualifier("reservePC")
    @Autowired(required = false)
    Computer reservePC;

    //获取laptop实例
    @Autowired(required = false)
    Laptop laptop;

    //获取phone实例
    @Autowired(required = false)
    Phone phone;

    //获取singlePhone实例
    @Autowired(required = false)
    SinglePhone singlePhone;


    //测试方法体,容器中是否有这些对象
    @Test
    void contextLoads() {
        System.out.println("reservePC:" + notebookPC);
        System.out.println("reservePC:" + reservePC);
        System.out.println("laptop:" + laptop);
        System.out.println("phone:" + laptop);
        System.out.println("singlePhone:" + singlePhone);
    }
}


//配置类
@Configuration
class BeanConfig {

    //注入notebookPC实例
    @Bean(name = "notebookPC")
    public Computer computer1(){
        return new Computer("笔记本电脑");
    }

    //当容器中没有Computer类时,注入reservePC实例
    @ConditionalOnMissingBean(Computer.class)
    @Bean("reservePC")
    public Computer computer2(){
        return new Computer("备用电脑");
    }

    //关键:测试只注入Computer类实例,未注入Tools类实例,@ConditionalOnMissingBean条件是否会向上检索到父类,即@ConditionalOnMissingBean条件是否是父类下的所有类型存在都生效,向下检索
    //当容器中没有Tools类时,注入laptop实例。Computer继承Tools类
    @ConditionalOnMissingBean(Tools.class)
    @Bean("laptop")
    public Laptop laptop(){
        return new Laptop("笔记本");
    }

    //拓展:验证是否向上检索
    //当容器中没有Phone类时,才注入。Phone类继承Conputer类
    @ConditionalOnMissingBean(Phone.class)
    @Bean("phone")
    public Phone phone(){
        return new Phone("手机");
    }

    //当容器中没有singlePhone类时,才注入。
    @ConditionalOnMissingBean(SinglePhone.class)
    @Bean("singlePhone")
    public SinglePhone singlePhone(){
        return new SinglePhone("Single手机");
    }

}


//Tools类
class Tools{
    private String name;
    public Tools() {
        this.name = name;
    }
}

//关键:Computer类,继承Tools类
class Computer extends Tools{
    private String name;
    public Computer(String name) {
        this.name = name;
    }
}

//Laptop类
class Laptop{
    private String name;
    public Laptop(String name) {
        this.name = name;
    }
}


//拓展:Phone类,继承Conputer类
class Phone extends Computer{

    private String name;

    public Phone() {
    }

    public Phone(String name) {
        this.name = name;
    }
}

//SinglePhone类
class SinglePhone{

    private String name;

    public SinglePhone() {
    }

    public SinglePhone(String name) {
        this.name = name;
    }
}

运行结果:

结论:

@ConditionalOnMissingBean 会识别到 参数中的类 的继承树,当容器中存在 该类该类的子类 或  该类的父类 的类型时,@ConditionalOnMissingBean 返回false ,使得 @ConditionalOnMissingBean 标注的类 不执行。

 

具体原理,还没找到,所以用简陋的方式进行验证。如果读者了解,请赐教。

 

 

 

 

 

 

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值