@Conditional注解,官方解释为:“只有当所有指定的条件都满足是,组件才可以注册”,主要的用处是在创建bean时增加一系列限制条件,在条件通过时,才可以成功创建bean。
Conditional的声明如下:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
Class<? extends Condition>[] value();
}
接收的参数是一个数组,数组元素是Condition类型,Condition是一个接口:
public interface Condition{
/** Determine if the condition matches.
* @param context the condition context
* @param metadata meta-data of the {@link AnnotationMetadata class} or
* {@link Method method} being checked.
* @return {@code true} if the condition matches and the component can be registered
* or {@code false} to veto registration.
*/
boolean matches(ConditionContext context, AnnotatedTypeMedata metadata);
}
当要自定义组件注册规则时,编写一个Condition的实现类即可,在实现类中定义通过的规则:
public class MyCondition1 implements Condition {
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
//IOC使用的beanFactory
ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
//类加载器
ClassLoader classLoader = conditionContext.getClassLoader();
//当前运行环境
Environment environment = conditionContext.getEnvironment();
//bean定义的注册类
BeanDefinitionRegistry registry = conditionContext.getRegistry();
//资源加载器
ResourceLoader resourceLoader = conditionContext.getResourceLoader();
if(registry.containsBeanDefinition("person")){
return true;
}
return false;
}
}
上述代码是我编写的一个Condition的实现类,规则是当容器中存在一个名为person的bean时,条件生效。可以通过conditionContext来获取更多的信息,用于自定义条件。
另外,我还定义了一个Condition的实现类,判断条件则和第一个的相反,在配置类中应用上@Condition
//配置类
@Configuration
public class MyConfig3 {
//@Lazy
@Bean("person")
public Person person(){
Person person = new Person("张三",20);
System.out.println(person);
return person;
}
@Conditional({MyCondition1.class})
@Bean
public Person p1(){
Person person = new Person("李四",21);
System.out.println(person);
return person;
}
@Conditional({MyCondition2.class})
@Bean
public Person p2(){
Person person = new Person("王五",22);
System.out.println(person);
return person;
}
}
//测试类
public class AnnotationTest {
@Test
public void testCondition(){
ApplicationContext ctx = new AnnotationConfigApplicationContext(MyConfig3.class);
}
}
输出结果:

配置类的代码中,我将@Lazy注解给注释掉了,如果放开该注释,那么,输出就只会是Person{name='王五',22},因为容器在创建时,因懒加载的缘故,person这个bean并没有被加载到容器当中,所以,另外一个条件生效,输出Person{name='王五',22}这样的结果