Spring. 条件化创建bean

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36420790/article/details/82759865

假设你希望某个 bean 只有在满足某个条件的时候才会创建,Spring 4 引入了一个新的 @Conditional 注解,它可以用到带有 @Bean 注解的方法上,如果给定的条件结果为 true,则创建这个 bean,否则,这个 bean 会被忽略。

以下是一个示例:

@Bean
@Conditional(MagicExistsCondition.class)
public MagicBean magicBean(){
    return new MagicBean();
}

注意到,magicBean 方法被 @Conditional 注解修饰,值为 MagicExistsCondition.class。

MagicExistsCondition.class:

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

作为 @Conditional 注解的值的类必须实现 Condition 接口,Condition 接口只有一个返回类型为 boolean 的 matches() 方法,Spring 将根据 matches() 方法的返回值来决定是否创建 bean,在上例中,matches() 方法检查环境中是否存在名为 magic 的环境属性,属性的值是什么无所谓,只要存在这个属性,matches() 方法就会返回 true,所带来的结果就是条件能够得到满足,所有 @Conditional 注解上引用 MagicExistsCondition 的 bean 都会被创建。

Condition 接口:

public interface Condition{
    boolean matches(ConditionContext ctxt, AnnotatedTypeMetadata metadata);
}

matches() 方法通过 ConditionContext 和 AnnotatedTypeMetadata 来做出决策。

ConditionContext 接口:

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

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

  • 借助 getRegistry() 返回的 BeanDefinitionRegistry 检查 bean 定义;
  • 借助 getBeanFactory() 返回的 ConfifurableListableBeanFactory 检查 bean 是否存在,甚至探查 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> getAllAnnotationAttrubutes(String annotationType, boolean classValuesAsString);
}
  • 借助 isAnnotated() 方法,我们能够判断带有 @Bean 注解的方法是不是还带有其他特定的注解
  • 借助其他的方法,我们能够检查 @Bean 注解的方法上其他注解的属性。

猜你喜欢

转载自blog.csdn.net/qq_36420790/article/details/82759865