@Conditional注解使用与自定义验证注解

@Conditional注解使用与自定义验证注解

作用:Spring4推出了@Conditional注解,方便程序根据当前环境或者容器情况来动态注入bean,按照一定的条件进行判断,满足条件给容器注册bean。

源码:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {

	/**
	 * All {@link Condition Conditions} that must {@linkplain Condition#matches match}
	 * in order for the component to be registered.
	 */
	Class<? extends Condition>[] value();//实现Condition类,定义bean是否注册的条件

}

参数value源码:

@FunctionalInterface
public interface Condition {

	/**
	 * Determine if the condition matches.确定条件是否匹配
	 * @param context the condition context
	 * @param metadata metadata of the {@link org.springframework.core.type.AnnotationMetadata class}
	 * or {@link org.springframework.core.type.MethodMetadata method} being checked
	 * @return {@code true} if the condition matches and the component can be registered,
	 * or {@code false} to veto the annotated component's registration
	 */
	boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);

}

demo:自定义是否注册bean的规则

  • 创建实体类

    public class User {
        private String name;
        private Integer age;
    
        public User(String name, Integer age) {
            this.name = name;
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
        ...
    }
    
  • 创建自定义bean注册校验规则

    当bean的名字为boy的时候注册,反之不注册

    public class BoyCondition implements Condition {
        //校验是否为boy类型的bean
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            StandardMethodMetadata standardMethodMetadata = null;
            //向下转型,为了使用子类的方法获取方法名
            if (metadata instanceof StandardMethodMetadata) {
                standardMethodMetadata = (StandardMethodMetadata) metadata;
            }
            //如果方法名不匹配,就去看@Bean注解是否定义了beanName
            if (!"boy".equals(standardMethodMetadata.getMethodName())) {
                MergedAnnotations annotations = metadata.getAnnotations();
                MergedAnnotation<Bean> beanMergedAnnotation = annotations.get(Bean.class);
                Map<String, Object> map = beanMergedAnnotation.asMap();
                String[] name = (String[]) map.get("name");
                //使用stream流判断是否符合条件,好处:延迟加载,当数组为空的时候,不会执行方法体中的内容,直接返回false
                if (!Stream.of(name).anyMatch(s -> "boy".equals(s))) {
                    return false;
                }
            }
            return true;
        }
    }
    
  • 创建UserBeanConfig类

    @Configuration
    public class UserBeanConfig {
        @Bean
        @Conditional(BoyCondition.class)
        public User boy(){
            return new User("boy",22);
        }
        @Bean
        @Conditional(BoyCondition.class)
        public User girl(){
            return new User("girl",22);
        }
    }
    
    
  • 测试类

    public static void main(String[] args) {
            AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(UserBeanConfig.class);
            Map<String, User> beansOfType = annotationConfigApplicationContext.getBeansOfType(User.class);
            System.out.println(beansOfType);
        }
    
    打印结果:{boy=User{name='boy', age=22}}
    当bean的名字不为boy的时候,不会创建bean
    
  • 注解源码中Class<? extends Condition>[] value()验证条件可以配置多个

    定义新的验证条件

    public class UserCondition implements Condition {
        @Override
        public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
            return false;
        }
    }
    
  • 修改UserBeanConfig类

    @Configuration
    @Conditional({BoyCondition.class,UserCondition.class})
    public class UserBeanConfig {
        @Bean(name = "boy")
        @Conditional({BoyCondition.class,UserCondition.class})
        public User boy(){
            return new User("boy",22);
        }
    }
    
    
  • 经过多次测试运行结果:

    @Conditional({BoyCondition.class,UserCondition.class}) 谁在前面先执行谁的验证(此时先执行BoyCondition)
    当BoyCondition返回ture,UserCondition返回false,那么bean不加载
    当BoyCondition返回true,UserCondition返回true,那么bean加载
    
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值