Spring4 条件化bean创建(Spring in action)
假设你希望一个或多个bean只有在应用的类路径下包含特定的库时才创建。或者我们希望某个bean只有当另外某个特定的bean也声明了之后才会创建。我们还可能要求只有某个特定的环境变量设置之后,才会创建某个bean
在Spring 4之前,很难实现这种级别的条件化配置,但是Spring 4引入了一个新的@Conditional注解,它可以用到带有@Bean注解的方法上。如果给定的条件计算结果为true,就会创建这个bean,否则的话,这个bean会被忽略。
设置给@Conditional的类可以是任意实现了Condition接口的类型。可以看出来,这个接口实现起来很简单直接,只需提供matches()方法的实现即可。如果matches()方法返回true,那么就会创建带有@Conditional注解的bean。如果matches()方法返回false,将不会创建这些bean。
public abstract interface Condition { public abstract boolean matches(ConditionContext paramConditionContext, AnnotatedTypeMetadata paramAnnotatedTypeMetadata); }
ConditionContext是一个接口,通过ConditionContext,我们可以做到如下几点:
1.借助getRegistry()返回的BeanDefinitionRegistry检查Bean定义;
2.借助getBeanFactory()返回的ConfigurableListableBeanFactory检查bean是否存在,甚至探查bean的属性;
3.借助getEnvironment()返回的Environment检查环境变量是否存在以及它的值是什么
4.读取并探查getResourceLoader()返回的ResourceLoader所加载的资源;
5.借助getClassLoader()返回的ClassLoader加载并检查类是否存在;
1 public abstract interface ConditionContext 2 { 3 public abstract BeanDefinitionRegistry getRegistry(); 4 5 public abstract ConfigurableListableBeanFactory getBeanFactory(); 6 7 public abstract Environment getEnvironment(); 8 9 public abstract ResourceLoader getResourceLoader(); 10 11 public abstract ClassLoader getClassLoader(); 12 }
AnnotatedTypeMetadata则能够让我们检查带有@Bean注解的方法上还有什么其他的注解。像ConditionContext一样,AnnotatedTypeMetadata也是一个接口。它如下所示:
借助isAnnotated()方法,我们能够判断带有@Bean注解的方法是不是还有其他特定的注解。借助其他的那些方法,我们能够检查@Bean注解的方法上其他注解的属性。
public abstract interface AnnotatedTypeMetadata { public abstract boolean isAnnotated(String paramString); public abstract Map<String, Object> getAnnotationAttributes(String paramString); public abstract Map<String, Object> getAnnotationAttributes(String paramString, boolean paramBoolean); public abstract MultiValueMap<String, Object> getAllAnnotationAttributes(String paramString); public abstract MultiValueMap<String, Object> getAllAnnotationAttributes(String paramString, boolean paramBoolean); }
浙公网安备 33010602011771号