@Conditional四个较常用的派生注解总结

该内容是在学习SpringBoot底层的时候,看到SpringBoot的使用,所以这的做一个简单的总结方便以后复习。可能会有一些问题,还望指出共同学习

@Conditional注解:

  • 作用:按照一定的条件进行判断,在满足给定条件后才会注册对应的bean对象到Spring的IOC容器中。
  • 位置:方法、类
  • @Conditional本身是一个父注解,派生出大量的子注解:
    • @ConditionalOnClass:注解用于基于类路径(Classpath)的条件装配
    • @ConditionalOnBean 注解会检查 IOC 容器中是否存在一个或多个指定的 Bean,只有在满足条件的情况下才会进行后续的自动配置
    • @ConditionalOnMissingBean:判断ioc中没有对应的bean(类型或名称),才注册bean到IOC容器。
    • @ConditionalOnProperty:判断配置文件中有对应属性和值,才注册bean到IOC容器。

下面就对@Conditional注解较常用的派生注解来做一个解释:

解释之前先对测试的结构做一个了解:

  1. 包结构

  1. 每个类的代码

    • pojo包
    /**
     * Parent类
     */
    public class Parent {
    }
    
    //
    /**
     * Child类
     */
    public class Child {
    }
    /
    /**
     * 其他类
     */
    public class Others {
    }
    
    • 配置类
    /**
     * 配置文件,对Bean的处理
     */
    @Configuration
    public class BeanConfig {
        
        @Bean
        public Child getChild(){
            return new Child();
        }
    }
    
@ConditionalOnClass

@ConditionalOnClass 注解用于基于类路径(Classpath)的条件装配,即根据某个类是否存在于 classpath 中进行条件判断,从而控制 Spring Boot 应用中 Bean(组件)是否需要被创建。

具体来说,@ConditionalOnClass 注解会检查指定类路径中的指定的类是否存在,如果该类在 Classpath 中,则会将当前的Bean放入到IOC容器中。反之,如果指定类没有存在于 Classpath 则不会 创建当前的Bean
常用的属性有:

  • name:需要是全路径类名,多个类名称使用逗号分隔。当有多个类名称,那么必须所有的类都存在时才会创建当前的Bean。

  • value : 会判断Classpath中是否有指定的字节码文件,如果有多个只有当都满足的情况才会创建当前Bean

        @Bean
        @ConditionalOnClass(name = {"com.yfs1024.pojo.Parent","com.yfs1024.pojo.Others"})
        public Child getChild(){
            return new Child();
        }
    

    当两个都存在时Spring会将当前@Bean注解修饰的方法的返回放入IOC容器,名字为方法名(下面就不在赘述)

    • 通过可视化界面可以看到,高亮部分是Spring默认生成,没有高亮是我们自己写的类

在这里插入图片描述

在这里插入图片描述

如果其中一个类不存在就不创建如图 2;

对于通过类型判断(注解中的value可以省略),也是如此,判断的是在编译之后有没有对应的字节码文件,代码如下:

    @Bean
    @ConditionalOnClass({Parent.class, Others.class})
    public Child getChild(){
        return new Child();
    }

此时编译之后的Classpath文件存在这两个文件的字节码文件,所以会将这个Bean放入到容器中。结果如图1;

@ConditionalOnBean

@ConditionalOnBean 它的作用是根据 Bean 的条件来控制某些 Bean 的加载和初始化。它可以被用于方法上面,表示只有在指定类型的 Bean 存在时才会进行方法的调用。也可以用于类上面,表示只有在指定类型的 Bean 存在时,该类才会被加载和初始化。

这个注解的参数常用的应该也是那两个 name:value : 当然还有type,annotation, 这里就不再介绍,等我用到了再补充

//	Class<?>[] value() default {};   当参数为value是传入的需要是字节码文件,即Class类的对象
/
	@Bean
    @ConditionalOnBean({Parent.class, Others.class})
    public Child getChild(){
        return new Child();
    }

此时因为IOC容器中并没有这个字节码类对象的两个对象,容器中的图如图2所示;

现在我们在Parent和Others上添加@Component注解让Spring扫描到,此时,容器中就有了这两个对象,如下,所以当前的方法的返回值就会放入到容器中。结果如图1所示:修改Parent和Others代码如下:

在这里插入图片描述

@Component
public class Others {
}
//
@Component
public class Parent {
}

另外也可以通过名称来限定是否创建,但是在此时可能就出现容器中并没有加入当前对象,即容器中没有getChild这个对象,但是有Others和Parent这两个对象的现象。此时我们就可以通过自己指定,来确定顺序。

原因: 这是因为在判断的时候其他的两个对象还没有创建

@Bean
@ConditionalOnBean(name = "getParent")
public Child getChild(){
    return new Child();
}

此时我们就可以通过自己指定,来确定顺序。

@Bean
public Parent getParent(){
    return new Parent();
}

@Bean
@ConditionalOnBean(name = "getParent")
public Child getChild(){
    return new Child();
}

此时再看就有了。解决。所以在这里也推荐使用value参数,较好。

@ConditionalOnMissingBean

当IOC容器 中不存在指定类型的Bean时,才会加载该Bean,否则将会忽略这个Bean。

常见的使用场景是:当某个类不存在时才创建对应的 Bean。

    @Bean
    public Parent getParent(){
        return new Parent();
    }


    @Bean
    @ConditionalOnMissingBean(name = "getPar2ent")
    public Child getChild(){
        return new Child();
    }

此时会创建因为容器中没有getPar2ent这个对象,如下,但是当为getParent,时就不会创建。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pKb9Th0b-1681145080120)(C:\Users\57589\AppData\Roaming\Typora\typora-user-images\image-20230410234600588.png)]

这个比较好理解,结果略过

@ConditionalOnProperty

@ConditionalOnProperty主要作用是根据应用程序的配置属性来决定是否创建 Bean.

常见的使用场景是:根据配置来控制某些 Bean 是否启用或者禁用,从而实现应用程序的灵活性和可配置性。
@ConditionalOnProperty 注解可以根据一或多个配置属性的值来决定是否创建 Bean,配置属性的值可以是 true、false、null、或者一个具体的字符串。
例如,我们需要根据某个配置属性来判断是否创建一个 Bean,可以这样写:

application.properties配置文件中

aliyun:
  oss:
    endpoint: hangzhou.aliyuncs
@Bean
@ConditionalOnProperty("aliyun.oss.endpoint")
public Others getOthers(){
    return new Others();
}

即当配置文件中有aliyun.oss.endpoint 这个配置的时候才创建当前的对象。结果如图

看到这里其实我们也就可以想到,为什么Mybatis在没有yml配置文件中配置时会报错,我猜就是这个原因

对于这个注解其中的几个参数就要学习一下了

  1. havingValue:指定配置属性的值与该属性值匹配时,创建 Bean,默认为 “”。
  2. matchIfMissing:指定当配置属性不存在时,是否创建 Bean,默认是 true。
  3. prefix:用于设置配置属性的前缀。
  4. name:用于指定配置属性的名称。
  5. value:用于指定配置属性的名称,与 name 属性类似。
  • havingValue
@Bean
@ConditionalOnProperty(value = "aliyun.oss.endpoint" , havingValue = "hangzhou.aliyuncs")
public Others getOthers(){
    return new Others();
}

此时因为我们指定的值和配置文件中的值相同,在此时就会创建当前的Bean

在这里插入图片描述

但是如果把后面的havingValue修改的和配置文件中不一致时,此时就不会创建Bean,比如修改为havingValue = "yfs1024"

  • boolean matchIfMissing() default false;

Spring给的解释:
Specify if the condition should match if the property is not set. Defaults to false.
Returns:
if the condition should match if the property is missing

翻译:指定如果未设置属性,则条件是否应匹配。默认为 false。返回:如果缺少属性,条件是否匹配

比如说我们把代码修改一下,把matchIfMissing设置为true,此时表示,即使配置文件没有这个配置依然创建Bean

注意:此时因为是多个参数,所以现在value就不可以省略了。

@Bean
@ConditionalOnProperty(value = "aliyun.oss.XXXX" , matchIfMissing=true)
public Others getOthers(){
    return new Others(); 	
}
  • String prefix( ) default “”;

在这里插入图片描述

在上述示例中,我们使用了 “aliyun.oss” 作为配置属性的前缀。 application.yml配置如下:

aliyun:
	oss: 
		enabled: true

那么就会创建一个 Others Bean。如果把 aliyun.oss.enabled 改成 false,或者删除该属性,Others 就不会被创建出来。
总之,@ConditionalOnProperty 注解的 prefix 属性可以指定配置属性的前缀,从而更好地管理和控制应用程序的配置属性。


先总结到这吧,睡觉

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yfs1024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值