美文网首页
@Conditional条件化Bean装配

@Conditional条件化Bean装配

作者: 妖云小离 | 来源:发表于2018-09-05 20:28 被阅读0次

    @Conditional 能解决什么问题

    可以使Bean在满足一定的条件Condition下才进行装配。

    条件Condition如何定义?

    实现Condition接口,重写matches()方法。
    返回true则条件成立,否则不成立。
    代码如下:

    import org.springframework.context.annotation.Condition;
    import org.springframework.context.annotation.ConditionContext;
    import org.springframework.core.type.AnnotatedTypeMetadata;
    
    public class ACondition implements Condition {
        @Override
        public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
       //doSomething
        }
    }
    

    可以看到matches方法提供了两个参数,是接口类型:
    ConditionContextAnnotatedTypeMetadata

    ConditionContext接口

    public interface ConditionContext {
    
        BeanDefinitionRegistry getRegistry();
    
        ConfigurableListableBeanFactory getBeanFactory();
    
        Environment getEnvironment();
    
        ResourceLoader getResourceLoader();
    
        ClassLoader getClassLoader();
    
    } 
    

    通过ConditionContext,我们可以做到如下几点:

    方法 作用
    getRegistry() 借助返回的BeanDefinitionRegistry检查bean的定义
    getBeanFactory() 借助返回的ConfigrableListableBeanFactory检查是否存在,甚至检查bean的属性
    getEnvironment() 借助返回Environment检查环境变量是否存在以及读取它的值是什么
    getResourceLoader() 读取并检查它返回的ResourceLoader所加载的资源
    getClassLoader() 借助它的返回的ClassLoader加载并检查类是否存在

    AnnotatedTypeMetadata接口

    public interface AnnotatedTypeMetadata {
    
        boolean isAnnotated(String annotationType);
    
        Map<String, Object> getAnnotationAttributes(String annotationType);
    
        Map<String, Object> getAnnotationAttributes(String annotationType, boolean classValuesAsString);
    
        MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationType);
    
        MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationType, boolean classValuesAsString);
    
    }
    
    

    AnnotatedTypeMetadataisAnnotated()方法,能够判断带有@Bean注解的方法是否有别的注解。其他的方法,能够获取@Bean注解的方法上其他注解的属性。

    @Conditional 如何使用

    直接上代码:

    @Service
    @Conditional(ACondition.class)
    @AConditionAnno
    public class AConditionServiceImpl implements ConditionService{
        @Override
        public String getName() {
            return this.getClass().getName();
        }
    }
    

    用法为:@Conditional(Condition.class)
    加上之后,SpringAConditionServiceImpl会根据AConditionmatches()方法的返回值来决定能否注册该Bean。

    Demo

    1.定义条件Condition

    public class ACondition implements Condition {
        @Override
        public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
            for (String name:conditionContext.getRegistry().getBeanDefinitionNames()
                 ) {
                System.out.println(name);
            }
            System.out.println(conditionContext.getBeanFactory().containsBean("BeforeAConditionBean")
                    +"/"+annotatedTypeMetadata.isAnnotated(AConditionAnno.class.getName()));
            return 
                annotatedTypeMetadata.isAnnotated(AConditionAnno.class.getName());
        }
    }
    

    上面的代码中:

    1. 通过ConditionContext打印当前所有已经注册的BeanID。
    2. 判断BeanID为BeforeAConditionBean的Bean是否已经创建。
    3. 判断需要创建的Bean是否带有AConditionAnno注解。

    2.为Bean加上条件注解@Conditional

    @Service
    @Conditional(ACondition.class)
    @AConditionAnno
    public class AConditionServiceImpl implements ConditionService{
        @Override
        public String getName() {
            return this.getClass().getName();
        }
    }
    

    3.测试类主方法

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class ConditionalTest {
    
        @Autowired
        ConditionService conditionService;
    
        @Test
        public void test(){
            System.out.println(conditionService.getName());
        }
    
    }
    

    不出意外,@Autowired是可以装配成功的。
    如果把AConditionServiceImpl类上的@AConditionAnno注解去掉,那么测试类报错,@Autowired找不到Bean。

    相关文章

      网友评论

          本文标题:@Conditional条件化Bean装配

          本文链接:https://www.haomeiwen.com/subject/kyszwftx.html