10、底层注解-@Conditional条件装配

条件装配:满足Conditional指定的条件,则进行组件注入

用@ConditionalOnMissingBean举例说明

@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingBean(name = "tom")//没有tom名字的Bean时,MyConfig类的Bean才能生效。
public class MyConfig {

    @Bean
    public User user01(){
        User zhangsan = new User("zhangsan", 18);
        zhangsan.setPet(tomcatPet());
        return zhangsan;
    }

    @Bean("tom22")
    public Pet tomcatPet(){
        return new Pet("tomcat");
    }
}

public static void main(String[] args) {
    //1、返回我们IOC容器
    ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

    //2、查看容器里面的组件
    String[] names = run.getBeanDefinitionNames();
    for (String name : names) {
        System.out.println(name);
    }

    boolean tom = run.containsBean("tom");
    System.out.println("容器中Tom组件:"+tom);//false

    boolean user01 = run.containsBean("user01");
    System.out.println("容器中user01组件:"+user01);//true

    boolean tom22 = run.containsBean("tom22");
    System.out.println("容器中tom22组件:"+tom22);//true

}

@Conditional源码

@Conditional来源于spring-context包下的一个注解。Conditional中文是条件的意思,@Conditional注解它的作用是按照一定的条件进行判断,满足条件给容器注册bean。

通过他的注解内部可以发现,他就是一个纯功能性注解,他并没有依赖于其他注解,类上只有三个元注解。

@Target({ElementType.TYPE, ElementType.METHOD}) 使用范围接口、类、枚举、注解、方法

@Retention(RetentionPolicy.RUNTIME): @Retention是用来修饰注解的生命周期的,RetentionPolicy.RUNTIME代表的是不仅被保存到class文件中,jvm加载class文件之后,仍然存在;一直有效!

@Documented: @Documented和@Deprecated注解长得有点像,@Deprecated是用来标注某个类或者方法不建议再继续使用,@Documented只能用在注解上,如果一个注解@B,被@Documented标注,那么被@B修饰的类,生成Javadoc文档时,会显示@B。

package org.springframework.context.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
    Class<? extends Condition>[] value();
}

@Conditional只有一个参数,并且这个参数要求是继承与Condition类,并且参数是个数组,也就是可以 传多个的。Condition类是一个函数式接口(只有一个方法的接口被称为函数式接口)。matches方法就是比较方法,如果为true则注入,如果为false则不注入。

@FunctionalInterface
public interface Condition {
    boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}

@Conditional扩展注解

而除了@Conditional注解外,springboot通过@Conditional注解又扩展了很多注解出来,如下@ConditionalOnBean、@ConditionalOnClass等等…

@ConditionalOnClass

主要是判断是否存在这个类文件,如果有这个文件就相当于满足条件,然后可以注入到容器当中。

当然并不是说容器里面是否有这个类哈,不要理解错了,这也就是我们有时候使用springboot只需要引入个依赖,框架就可以用的原因!

@ConditionalOnMissingClass

@ConditionalOnMissingClass只有一个value属性。他和@ConditionalOnClass功能正好相反。@ConditionalOnClass是class存在为true,而@ConditionalOnMissingClass是不存在为true,也就是存在为false。为fasle就意味着不注入。

@ConditionalOnBean

bean存在的时候注入,不存在的时候不注入,这块就是指的spring的ioc容器了。

@ConditionalOnMissingBean

bean不存在的时候注入,存在的时候为false。跟@ConditionalOnBean正好是相反的。

@ConditionalOnProperty

@ConditionalOnProperty主要可用于通过和springboot当中application配置文件来使用。在实战当中我们也可以通过他来实现配置化管理bean。

其他注解

  • @ConditionalOnJava:只有运行指定版本的 Java 才会加载 Bean

  • @ConditionalOnWebApplication 和 @ConditionalOnNotWebApplication:只有运行在(不在)web 应用里才会加载这个 bean

  • @ConditionalOnCloudPlatform:只有运行在指定的云平台上才加载指定的 bean

  • @ConditionalOnJndi:只有指定的资源通过 JNDI 加载后才加载 bean

  • @ConditionalOnExpression(“${test.express}==true”) :可通过spring提供的spEL表达式灵活配置,当表达式为true的时候,才会实例化一个Bean

  • @ConditionalOnSingleCandidate(UserService.class) :表示ioc容器中只有一个UserService类型的Bean,才生效

  • @ConditionalOnResource:指定的静态资源⽂件存在 才加载

————————————————

引用原文链接:https://blog.csdn.net/weixin_43888891/article/details/127503336

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值