Spring Boot 运行原理 - 核心注解
2017-04-26 17:15
1336 查看
3 核心注解
打开任意*AutoConfiguration文件,一般都有下面的条件注解,在spring-boot-autoconfigure-1.5.3.RELEASE.jar的org.springframework.boot.autoconfigure.condition包下条件注解如下:@ConditionalOnBean:当前容器有指定Bean的条件下。
@ConditionalOnClass:当前类路径下有指定的类的条件下。
@ConditionalOnExpression:基于SpEL表达式作为判断条件。
@ConditionalOnJava:基于JVM版本作为判断条件。
@ConditionalOnJndi:在JNDI存在的条件下查找指定的位置。
@ConditionalOnMissingBean:当容器里没有指定Bean的情况下。
@ConditionalOnMissingClass:当类路径下没有指定的类的条件下。
@ConditionalOnNotWebApplication:当前项目不是WEB项目的条件下。
@ConditionalOnProperty:指定属性是否有指定的值。
@ConditionalOnResource:类路径是否有指定的值。
@ConditionalOnSingleCandidate:当指定Bean在容器中只有一个,或者虽然有多个但 是指定首选的Bean。
@ConditionalOnWebApplication:当前项目是WEB项目的条件下。
这些注解都组合了@Conditional元注解,只是使用了不同的条件(Conditional),Spring 条件注解(@Conditional)我们介绍过根据不同条件创建不同Bean。
简单分析一下@ConditionalOnWebApplication注解:
package org.springframework.boot.autoconfigure.condition; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.context.annotation.Conditional; @Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Documented @Conditional(OnWebApplicationCondition.class) public @interface ConditionalOnWebApplication { }
从源码我们可以看出,此注解使用的条件是OnWebApplicationCondition类,下面我们看看这个类是怎么构造的:
package org.springframework.boot.autoconfigure.condition; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.core.type.AnnotatedTypeMetadata; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.StandardServletEnvironment; @Order(Ordered.HIGHEST_PRECEDENCE + 20) class OnWebApplicationCondition extends SpringBootCondition { private static final String WEB_CONTEXT_CLASS = "org.springframework.web.context." + "support.GenericWebApplicationContext"; @Override public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { boolean webApplicationRequired = metadata .isAnnotated(ConditionalOnWebApplication.class.getName()); ConditionOutcome webApplication = isWebApplication(context, metadata); if (webApplicationRequired && !webApplication.isMatch()) { return ConditionOutcome.noMatch(webApplication.getMessage()); } if (!webApplicationRequired && webApplication.isMatch()) { return ConditionOutcome.noMatch(webApplication.getMessage()); } return ConditionOutcome.match(webApplication.getMessage()); } private ConditionOutcome isWebApplication(ConditionContext context, AnnotatedTypeMetadata metadata) { if (!ClassUtils.isPresent(WEB_CONTEXT_CLASS, context.getClassLoader())) { return ConditionOutcome.noMatch("web application classes not found"); } if (context.getBeanFactory() != null) { String[] scopes = context.getBeanFactory().getRegisteredScopeNames(); if (ObjectUtils.containsElement(scopes, "session")) { return ConditionOutcome.match("found web application 'session' scope"); } } if (context.getEnvironment() instanceof StandardServletEnvironment) { return ConditionOutcome .match("found web application StandardServletEnvironment"); } if (context.getResourceLoader() instanceof WebApplicationContext) { return ConditionOutcome.match("found web application WebApplicationContext"); } return ConditionOutcome.noMatch("not a web application"); } }
从isWebApplication方法可以看出,判断条件是:
GenericWebApplicationContext是否在类路径中;
容器中是否有名为session的scope;
当前容器的Enviroment是否为StandardServletEnvironment;
当前的ResourceLoader是否是WebApplicationContext(ResourceLoader是ApplicationContext的顶级接口之一);
我们需要构建ConditionOutcome类的对象来帮助我们,最终通过ConditionOutcome.isMatch方法返回值来确定条件。
相关文章推荐
- 20-SpringBoot——核心-运行原理
- 【SpringBoot】的核心配置和运行原理
- Spring Boot核心原理-自动配置 以及@ConfigurationProperties 注解
- springboot 入门教程(3)-运行原理、关键注解和配置
- SpringBoot15-springboot核心-Spring Boot运行原理
- 微服务:Spring Boot第二篇——运行原理和HelloWorld
- spring boot 原理、demo 与打包运行
- Spring Boot运行原理
- Spring Boot核心原理-自动配置
- Spring Boot核心-核心注解、自动配置、自定义banner
- 《02.Spring Boot实战:Spring Boot核心原理剖析》
- SpringBoot运行原理的分析:
- Spring Boot WAR包运行原理分析
- Spring Boot核心原理-自动配置
- spring boot学习笔记(5)springboot运行原理
- spring boot 运行jsp原理分析
- springboot自动配置的核心原理
- Spring Boot核心原理-自动配置
- Spring Boot 运行原理 - 查看Spring Boot自动配置项
- Spring Boot 运行原理 - 运作原理