当前位置: 代码网 > it编程>编程语言>Java > SpringBoot中condition注解的使用方式

SpringBoot中condition注解的使用方式

2024年05月19日 Java 我要评论
在项目中,有时会遇到我们的configuration、bean、service等等的bean组件需要依条件按需加载的情况。springboot中提供了一系列@condition* 注解来处理有条件注入

在项目中,有时会遇到我们的configuration、bean、service等等的bean组件需要依条件按需加载的情况。

springboot中提供了一系列@condition* 注解来处理有条件注入的情况。

说明

spring4中增加了@condition annotation, 使用该annotation之后,在做依赖注入的时候,会检测是否满足某个条件来决定是否注入某个类。

springboot基于spring4的这个注解实现了多个用于判断的条件注解,如果我们在使用中这些注解无法满足我们的要求还可以使用@conditional自定义条件注解

常用的条件注解

条件注解对应的condition 处理类处理逻辑
@conditionalonbeanonbeanconditionspring容器中是否存在对应的实例。可以通过实例的类型、类名、注解、昵称去容器中查找(可以配置从当前容器中查找或者父容器中查找或者两者一起查找)
@conditionalonclassonclasscondition类加载器中是否存在对应的类。可以通过class指定(value属性)或者class的全名指定(name属性)如果是多个类或者多个类名的话,关系是”与”关系,也就是说这些类或者类名都必须同时在类加载器中存在
@conditionalonexpressiononexpressioncondition判断spel 表达式是否成立
@conditionalonmissingbeanonbeanconditionspring容器中是否缺少对应的实例。可以通过实例的类型、类名、注解、昵称去容器中查找(可以配置从当前容器中查找或者父容器中查找或者两者一起查找)
@conditionalonmissingclassonclasscondition跟conditionalonclass的处理逻辑一样,只是条件相反,在类加载器中不存在对应的类
@conditionalonpropertyonpropertycondition应用环境中的屬性是否存在。提供prefix、name、havingvalue以及matchifmissing属性。prefix表示属性名的前缀,name是属性名,havingvalue是具体的属性值,matchifmissing是个boolean值,如果属性不存在,这个matchifmissing为true的话,会继续验证下去,否则属性不存在的话直接就相当于匹配不成功
@conditionalonresourceonresourcecondition是否存在指定的资源文件。只有一个属性resources,是个string数组。会从类加载器中去查询对应的资源文件是否存在
@conditionalonsinglecandidateonbeanconditionspring容器中是否存在且只存在一个对应的实例。只有3个属性value、type、search。跟conditionalonbean中的这3种属性值意义一样
@conditionalonwebapplicationonwebapplicationcondition应用程序是否是web程序,没有提供属性,只是一个标识。会从判断web程序特有的类是否存在,环境是否是servlet环境,容器是否是web容器等

举例

例子说明
@conditionalonbean(javax.sql.datasource.class)spring容器或者所有父容器中需要存在至少一个javax.sql.datasource类的实例
@conditionalonclass({ configuration.class,freemarkerconfigurationfactory.class })类加载器中必须存在configuration和freemarkerconfigurationfactory这两个类
@conditionalonexpression(“’${server.host}’==’localhost’”)server.host配置项的值需要是localhost
conditionalonjava(javaversion.eight)java版本至少是8
@conditionalonmissingbean(value = errorcontroller.class, search = searchstrategy.current)spring当前容器中不存在errorcontroller类型的bean
@conditionalonmissingclass(“genericobjectpool”)类加载器中不能存在genericobjectpool这个类
@conditionalonnotwebapplication必须在非web应用下才会生效
@conditionalonproperty(prefix = “spring.aop”, name = “auto”, havingvalue = “true”, matchifmissing = true)应用程序的环境中必须有spring.aop.auto这项配置,且它的值是true或者环境中不存在spring.aop.auto配置(matchifmissing为true)
@conditionalonresource(resources=”mybatis.xml”)类加载路径中必须存在mybatis.xml文件
@conditionalonsinglecandidate(platformtransactionmanager.class)spring当前或父容器中必须存在platformtransactionmanager这个类型的实例,且只有一个实例
@conditionalonwebapplication必须在web应用下才会生效

自定义条件注解

实现条件化注解我们需要两个类

  • 自定义注解类
  • 定义注解,指定判断用的条件类
  • 条件类
  • 实现org.springframework.context.annotation.condition接口,定义判断条件

举例说明

1.定义注解类myconditionalonproperty

要使用注解@conditional(myonpropertycondition.class),myonpropertycondition为我们要定义的条件类

@retention(retentionpolicy.runtime)
@target({elementtype.type, elementtype.method})
@documented
@conditional(myonpropertycondition.class)
public @interface myconditionalonproperty {
    string value();
    string prefix() default "";
    string havingvalue() default "";
    boolean matchifmissing() default false;
    boolean relaxednames() default true;
    //todo add one property
    string havingvalue() default "";
}

2.定义条件类:

public class myonpropertycondition implements condition {
    @override
    public boolean matches(conditioncontext context, annotatedtypemetadata metadata) {
        map<string, object> annotationattributes = metadata.getannotationattributes(myconditionalonproperty.class.getname());
        string propertyname = (string) annotationattributes.get("value");
        string value = annotationattributes.get("havingvalue");
        string propertyvalue = context.getenvironment().getproperty(propertyname);
       
        if (propertyvalue.equalsignorecase(value)) {
            return true;
        }
        return false;
    }
}

3.调用

   @configuration
    public class myconfig {
        @bean
        @myconditionalonproperty(value = "env",havingvalue = "dev")
        public person person(){
            log.info("创建bean");
            return new person();
        }
    }

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com