Spring实战 : Spring高级装配之条件化的bean(@Conditional注解)

条件化的bean:(利用@Conditional注解)
其中用到的两个接口(ConditionContext接口和Condition接口)
@Condition注解,可以将其用到带有@Bean注解的方法上。如果@Condition注解中通过给定的条件计算结果为true,就会创建这个bean,否则,这个bean就会被忽略。

public class practice {
    @Bean
    @Conditinoal(MagicExistsCondition.class)
     //MagicExistsCondition为设置给@Conditional的类(该类实现了Condition接口)
    public MagicBean magicBean(){
        return new MagicBean();
    }
}

//Condition接口(含有一个matches方法用来判断给定条件是否满足)
public interface Condition{
    boolean matches(ConditionContext ctxt, AnnotatedType metadata);
}

eg.假设有一个名为MagicBean的类,在只有设置了magic环境属性的时候,Spring才会实例化这个类(即这是一个条件)。如果环境中没有这个属性,那么MagicBean将会被忽略。
所以在本例中,需要创建Condition的实现并根据环境中是否存在magic属性来做出决策:

//在Condition接口的基础上,MagicExistsCondition类将特定条件通过Condition来实现
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.utill.ClassUtils;

public class MagicExistsCondition implements Condition{
    boolean matches(ConditionContext context, AnnotatedType medata){
        Environment env = context.getEnvironment();
        return env.containsProperty("magic"); //检查magic属性
    }
}

ConditionContext接口:

//本例中只是使用了ConditionContext接口的getEvironment()方法
public interface ConditionContext{
    BeanDefinitionRegistry getRegistry();
    //返回的BeanDefinitionRegistry检查bean定义
    ConfigurableListableBeanFactory getBeanFactory();
    //返回的ConfigurableListableBeanFactory检查bean是否存在,甚至探查bean的属性
    Environment getEnvironment();
    //返回的Environment检查环境变量是否存在以及它的值是什么
    ResourceLoader getResourceLoader();
    //返回的ResourceLoader所加载的资源
    ClassLoader getClassLoader();
    //返回的ClassLoader加载并检查类是否存在
}

AnnotatedTypeMetadata接口:(能够让我们检查带有@Bean注解的方法上还有什么其他的注解。)

//类似于ConditionContext接口,AnnotationTypeMetadata接口如下:
public interface AnnotatedTypeMetadata{
    boolean isAnnotated(String annotationType);
    //此方法能够判断带有@Bean注解的方法是不是还有其他特定的注解(借助其他的那些方法,就能偶检查@Bean注解的方法上其他注解的属性。)
    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);
}

@Profile注解就是基于@Conditional注解和Condition接口的:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Documented
@Conditional(ProfileCondition.class) //引用了ProfileCondition类来实现Condition接口
public @interface Profile{
    String[] value();
}

ProfileCondition用来检查某个bean profile是否可用:(下面是其实现)

你可能感兴趣的:(Spring实战)