今天主要从以下几方面来介绍一下@Conditional注解

  • @Conditional注解是什么

  • @Conditional注解怎么使用

1,@Conditional注解是什么


@Conditional注解是可以根据一些自定义的条件动态的选择是否加载该bean到springIOC容器中去,如果看过springBoot源码的同学会发现,springBoot中大量使用了该注解


2,@Conditional注解怎么使用


查看@Conditional源码你会发现它既可以作用在方法上,同时也可以作用在上,源码如下:


@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
   /**
    * All {@link Condition}s that must {@linkplain Condition#matches match}
    * in order for the component to be registered.
    */

   Class<? extends Condition>[] value();
}


a,@Conditional作用在方法上


定义一个Condition如下:


/**
* 定义一个bean的Condition
*
* @author zhangqh
* @date 2018年5月1日
*/

public class MyCondition implements Condition {
   public boolean matches(ConditionContext context,AnnotatedTypeMetadata metadata) {
       Environment env = context.getEnvironment();
       String system = env.getProperty("os.name");
       System.out.println("系统环境为 ==="+system);
       // 系统环境在Windows才加载该bean到容器中
       if(system.contains("Windows")){
           return true;
       }
       return false;
   }
}


定义一个bean加上@Conditional注解如下:


@Conditional({MyCondition.class})
@Bean(value="user1")
public User getUser1(){
   System.out.println("创建user1实例");
   return new User("李四",26);
}


测试如下:


AnnotationConfigApplicationContext applicationContext2 = new AnnotationConfigApplicationContext(MainConfig.class);
String[] beanNames = applicationContext2.getBeanDefinitionNames();
for(int i=0;i<beanNames.length;i++){
   System.out.println("bean名称为==="+beanNames[i]);
}


运行结果:


bean名称为===mainConfig
bean名称为===user0
bean名称为===user1


我这边电脑系统是window所以user1实例是有创建出来的,如果把MyCondition中的判断改成if(system.contains("linux"))那么user1是不会加载到spring容器中的


b,@Conditional作用在类上


修改注解配置如下:


/**
* 定义一个注解配置文件 必须要加上@Configuration注解
*
* @author zhangqh
* @date 2018年4月30日
*/

@Conditional({MyCondition.class})
@Configuration
public class MainConfig {
   /**
    * 定义一个bean对象
    * @return
    */

   @Scope
   @Lazy
   @Bean(value="user0")
   public User getUser(){
       System.out.println("创建user实例");
       return new User("张三",26);
   }
   //@Conditional({MyCondition.class})
   @Bean(value="user1")
   public User getUser1(){
       System.out.println("创建user1实例");
       return new User("李四",26);
   }
}


运行测试:


bean名称为===mainConfig
bean名称为===user0
bean名称为===user1


MainConfig中的bean都成功打印出来了,因为我MyCondition条件返回的是true,同样如果我修改成if(system.contains("linux"))那么MainConfig的bean就都不会实例化了


以上是今天文章的所有内容,欢迎大家吐槽



更多优质文章请关注以下公众号查阅:


一分钟学会spring注解之@Conditional注解_java