Spring@Conditional注解的使用
2018-02-05 10:30
501 查看
Spring3开始提供的profile机制用起来的确很爽,在Spring4中提供了一种更通用的条件化Bean定义机制。
定义一个Bean,这个Bean只有在满足MagicExistCondition中定义的条件时才会创建。
这里的@Conditional注解定义如下:
实现Condition接口
这里的matches方法有两个参数,分别为ConditionContext,AnnotatedTypeMetadata类型
ConditionContext
AnnotatedTypeMetadata
可以看以下ProfileCondition的实现
另外SpringBoot还提供了很多类似于@Profile的注解:
如果有机会再后续的文章中会对SpringBoot的自动化配置进行详细分析。
参考:
Spring In Action
Spring Framework Documentation
@Conditional注解
使用@Conditional注解定义一个Bean,这个Bean只有在满足MagicExistCondition中定义的条件时才会创建。
@Bean @Conditional(MagicExistCondition.class) public MagicBean magicBean() { return new MagicBean(); }
这里的@Conditional注解定义如下:
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Conditional { /** * 我们需要实现Condition接口,并实现他的matches方法 */ Class<? extends Condition>[] value(); }
实现Condition接口
public class MagicExistCondition implements Condition { /** * 如果返回true,Bean将会被创建并注册到Spring容器中;否则不会创建Bean */ public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { Environment env = context.getEnvironment(); // 当定义了magic属性的时候返回true return env.containsProperty("magic"); } }
这里的matches方法有两个参数,分别为ConditionContext,AnnotatedTypeMetadata类型
ConditionContext
/** * 包含了可能被Condition用到的所有信息 * @since 4.0 */ public interface ConditionContext { /** * 包含了用于描述Bean实例的BeanDefinition */ BeanDefinitionRegistry getRegistry(); /** * Spring容器,可以检查某些Bean是否存在 */ ConfigurableListableBeanFactory getBeanFactory(); /** * 当前应用包含的环境变量 */ Environment getEnvironment(); /** * 可以用来加载外部文件 */ ResourceLoader getResourceLoader(); /** * 类加载器 */ ClassLoader getClassLoader(); }
AnnotatedTypeMetadata
public interface AnnotatedTypeMetadata { /** * 查看@Bean注解的方法是否有annotationName参数指定的注解 */ boolean isAnnotated(String annotationName); /** * 如果@Bean注解的方法有annotationName参数指定的注解, * 可以通过这个方法获取这个注解下的所有属性; * 如果没有这个注解,将会返回null */ Map<String, Object> getAnnotationAttributes(String annotationName); /** * classValuesAsString参数为true,将注解中Class类型的属性以String的形式返回。 */ Map<String, Object> getAnnotationAttributes(String annotationName, boolean classValuesAsString); MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName); MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName, boolean classValuesAsString); }
Spring4对@Profile注解进行的重构
从Spring4开始,@Profile注解使用@Conditional注解实现。我们可以以它为例,学习如何使用@Conditional注解。/** * @since 3.1 */ @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented // 使用@Conditional注解,并定义了ProfileCondition @Conditional(ProfileCondition.class) public @interface Profile { String[] value(); }
可以看以下ProfileCondition的实现
/** * @since 4.0 */ class ProfileCondition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { if (context.getEnvironment() != null) { // 获取Profile注解的所有属性 MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName()); if (attrs != null) { // 遍历注解中value属性的所有元素 for (Object value : attrs.get("value")) { // 检查@Profile注解中的是否处于激活状态 if (context.getEnvironment().acceptsProfiles(((String[]) value))) { return true; } } return false; } } return true; } }
SpringBoot自动化配置中的Condition
Spring中的自动化配置基本就是靠这个@Condition注解实现的,所以在springboot-autoconfig中有一大堆实现了Condition接口的类:另外SpringBoot还提供了很多类似于@Profile的注解:
如果有机会再后续的文章中会对SpringBoot的自动化配置进行详细分析。
参考:
Spring In Action
Spring Framework Documentation
相关文章推荐
- spring boot 条件注解的使用@Conditional;@Conditional 可以根据条件,创建不同的bean,
- Spring @Conditional注解的使用
- Spring Boot2.x-06Spring Boot基础-使用@Conditional注解根据特定的条件装配bean
- spring @conditional注解的使用
- Spring @Conditional注解的使用
- 【Spring】22、Spring缓存注解@Cache使用
- Hibernate注解使用以及Spring整合
- 使用spring aop + 注解完成对业务操作的日志记录
- Spring、使用注解方式装配对象(@Resource、@Autowired)
- (10) 使用Spring的注解方式实现AOP入门 以及 细节
- 使用注解配置spring
- Spring及springmvc注解(annotation)使用详解
- 有关spring的依赖注入和@resource注解的使用
- spring 使用@scheduled注解执行定时任务
- 使用 Spring 2.5 基于注解驱动的 Spring MVC--转
- 在Spring Boot中使用 @ConfigurationProperties 注解
- 被事务代理的spring service 使用注解方式发布Dubbo服务
- Spring注解使用注意点
- spring注解开发AnnotationConfigApplicationContext的使用
- 如何使用Spring全注解开发大型商业ERP项目谁有呀?给指个明路