https://www.jianshu.com/p/23f504713b94

核心注解

打开上面任意一个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方法可以看出,判断条件是:

  1. GenericWebApplicationContext是否在类路径中;
  2. 容器中是否有名为session的scope;
  3. 当前容器的Enviroment是否为StandardServletEnvironment;
  4. 当前的ResourceLoader是否是WebApplicationContext(ResourceLoader是ApplicationContext的顶级接口之一);
  5. 我们需要构建ConditionOutcome类的对象来帮助我们,最终通过ConditionOutcome.isMatch方法返回值来确定条件。

Spring Boot 运行原理 - 核心注解的更多相关文章

  1. Spring Boot运行原理

    概述 本文主要写了下Spring Boot运行原理,还有一个小例子. Spring4.x提供了基于条件来配置Bean的能力,而Spring Boot的实现也是基于这一原理的. Spring Boot关 ...

  2. Spring boot运行原理-自定义自动配置类

    在前面SpringBoot的文章中介绍了SpringBoot的基本配置,今天我们将给大家讲一讲SpringBoot的运行原理,然后根据原理我们自定义一个starter pom. 本章对于后续继续学习S ...

  3. Spring Boot 运行原理

    Spring Boot并没有任何新的技术,全都是基于Spring4提供的技术,用优秀的设计,为Web开发提供了一套新的方式. 在HelloWorld中,我们没有进行任何显示的配置,但是程序还是运行起来 ...

  4. Spring Boot的27个注解【核心】

    导读[约定大于配置] Spring Boot方式的项目开发已经逐步成为Java应用开发领域的主流框架,它不仅可以方便地创建生产级的Spring应用程序,还能轻松地通过一些注解配置与目前比较火热的微服务 ...

  5. Spring Boot 运作原理

    Spring Boot 运作原理 1.Spring Boot 简介 SpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了 ...

  6. Spring Boot启动原理解析

    Spring Boot启动原理解析http://www.cnblogs.com/moonandstar08/p/6550758.html 前言 前面几章我们见识了SpringBoot为我们做的自动配置 ...

  7. spring boot启动原理步骤分析

    spring boot最重要的三个文件:1.启动类 2.pom.xml 3.application.yml配置文件 一.启动类->main方法 spring boot启动原理步骤分析 1.spr ...

  8. struts1,struts2,hibernate,spring的运行原理结构图

    一.struts1运行原理 1.初始化:struts框架的总控制器ActionServlet是一个Servlet,它在web.xml中配置成自动启动的Servlet,在启动时总控制器会读取配置文件(s ...

  9. spring boot 运行提示:Process finished with exit code 1

    spring boot 运行提示:Process finished with exit code 1 经检查发现是由于在application.properties配置文件中将某些自定义配置项移除了, ...

随机推荐

  1. curl tftp libcurl 功能使用

    #include <curl/curl.h> static size_t read_callback(void *ptr, size_t size, size_t nmemb, void ...

  2. springcloud学习之路: (五) springcloud集成SpringCloudConfig分布式配置中心

    SpringCloud全家桶中的分布式配置中心SpringCloudConfig, 它使用git来管理配置文件, 在修改配置文件后只需要调用一个接口就可以让新配置生效, 非常方便. SpringClo ...

  3. 理解serialVersionUID是什么?有什么用?如何生成?

    如果您曾经实现过Serializable接口,则必须遇到此警告消息 The serializable class xxx does not declare a static final serialV ...

  4. JPA-save()方法会将字段更新为null的解决方法

    今天在开发上碰到一个问题,在做页面展示的时候传给前端十个字段,前端修改了其中3个的值,所以只传了3个值给后端,其余字段默认为null,更新后其他7个字段在全部变为了空值. 在前端没法全量回传所有属性的 ...

  5. Leetcode练习

    1. 两数相加 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这 ...

  6. USACO Buying Hay

    洛谷 P2918 [USACO08NOV]买干草Buying Hay https://www.luogu.org/problem/P2918 JDOJ 2592: USACO 2008 Nov Sil ...

  7. 解决 SpringMVC 非spring管理的工具类使用@Autowired注解注入DAO为null的问题

    在SpringMVC框架中,我们经常要使用@Autowired注解注入Service或者Mapper接口,我们也知道,在Controller层中注入service接口,在service层中注入其它的s ...

  8. Linux性能优化实战学习笔记:第四讲

    一.怎么查看系统上下文切换情况 通过前面学习我么你知道,过多的上下文切换,会把CPU时间消耗在寄存器.内核栈以及虚拟内存等数据的保存和回复上,缩短进程真正运行的时间,成了系统性能大幅下降的一个元凶 既 ...

  9. AOP小记

    编程思想演进:POP(Procedure Oriented Programming)-> OOP(Object Oriented Programming)-> AOP(Aspect Ori ...

  10. 热情组——项目冲刺 Day4

    项目相关 作业相关 具体描述 班级 班级链接 作业要求 链接地址 团队名称 热情组 作业目标 实现软件制作,以及在福大的传播 Github链接 链接地址 SCRUM部分: 成员昵称 昨日目标 开始时间 ...