Spring Boot 运行原理 - 核心注解
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方法可以看出,判断条件是:
- GenericWebApplicationContext是否在类路径中;
- 容器中是否有名为session的scope;
- 当前容器的Enviroment是否为StandardServletEnvironment;
- 当前的ResourceLoader是否是WebApplicationContext(ResourceLoader是ApplicationContext的顶级接口之一);
- 我们需要构建ConditionOutcome类的对象来帮助我们,最终通过ConditionOutcome.isMatch方法返回值来确定条件。
Spring Boot 运行原理 - 核心注解的更多相关文章
- Spring Boot运行原理
概述 本文主要写了下Spring Boot运行原理,还有一个小例子. Spring4.x提供了基于条件来配置Bean的能力,而Spring Boot的实现也是基于这一原理的. Spring Boot关 ...
- Spring boot运行原理-自定义自动配置类
在前面SpringBoot的文章中介绍了SpringBoot的基本配置,今天我们将给大家讲一讲SpringBoot的运行原理,然后根据原理我们自定义一个starter pom. 本章对于后续继续学习S ...
- Spring Boot 运行原理
Spring Boot并没有任何新的技术,全都是基于Spring4提供的技术,用优秀的设计,为Web开发提供了一套新的方式. 在HelloWorld中,我们没有进行任何显示的配置,但是程序还是运行起来 ...
- Spring Boot的27个注解【核心】
导读[约定大于配置] Spring Boot方式的项目开发已经逐步成为Java应用开发领域的主流框架,它不仅可以方便地创建生产级的Spring应用程序,还能轻松地通过一些注解配置与目前比较火热的微服务 ...
- Spring Boot 运作原理
Spring Boot 运作原理 1.Spring Boot 简介 SpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了 ...
- Spring Boot启动原理解析
Spring Boot启动原理解析http://www.cnblogs.com/moonandstar08/p/6550758.html 前言 前面几章我们见识了SpringBoot为我们做的自动配置 ...
- spring boot启动原理步骤分析
spring boot最重要的三个文件:1.启动类 2.pom.xml 3.application.yml配置文件 一.启动类->main方法 spring boot启动原理步骤分析 1.spr ...
- struts1,struts2,hibernate,spring的运行原理结构图
一.struts1运行原理 1.初始化:struts框架的总控制器ActionServlet是一个Servlet,它在web.xml中配置成自动启动的Servlet,在启动时总控制器会读取配置文件(s ...
- spring boot 运行提示:Process finished with exit code 1
spring boot 运行提示:Process finished with exit code 1 经检查发现是由于在application.properties配置文件中将某些自定义配置项移除了, ...
随机推荐
- LeetCode——Rank Scores
Write a SQL query to rank scores. If there is a tie between two scores, both should have the same ra ...
- sparkSQL中的example学习(2)
UserDefinedUntypedAggregate.scala(默认返回类型为空,不能更改) import org.apache.spark.sql.{Row, SparkSession} imp ...
- 【MongoDB详细使用教程】三、高级查询
目录 1.使用比较运算符查询 2.使用关键字查询 2.1.in/not in 关键字 2.2.size 关键字 2.3.exists 关键字 2.4.or 关键字 3.模糊查询 4.查询结果排序 5. ...
- Centos 7 修改网卡名称、静态IP
修改内核选项 # vim /etc/sysconfig/grub GRUB_TIMEOUT= GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc ...
- 关于微信小程序中遇到的各种问题汇总(持续更新)
1.关于 <input />标签容易忽略的问题: 使用<input />标签时容易忘记绑定bindblur()方法(输入框失去焦点时触发),因为用户用键盘输入时不一定会点击完成 ...
- Paxos算法—前世
Paxos算法是基于消息传递且具有高度容错特性的一致性算法.我们将从一个简单的问题开始,逐步的改进我们的设计方案,最终得到Paxos,一个可以在逆境下工作的协议. 一.客户端-服务器模型 我们从最小的 ...
- 06点击事件 tabBar配置 拨打电话
1== D:\wxxm 项目的地址 2==>tabBar在全局配置中 在pages的同级目录下创建images本地图标 (最好的是在远程获取img 因为微信是有大小限制的) selectedIc ...
- 每天一套题打卡|河南省第八届ACM/ICPC
A 挑战密室 化学方程式求分子量 这题我懒得写了 可以用map<string,int>哈希表,表示每种分子的相对分子质量 之后,从头遍历到尾. 1.数字:连读直到不是数字 2.字母:连读直 ...
- v8
V8 - 开源,由Google开发,用C ++编写 Rhin- 由Mozilla基金会开源,完全用Java开发 SpiderMonkey 第一个JavaScript引擎,Netscape Naviga ...
- Portainer
docker search portainer docker pull portainer/portainer docker run -it \ --name prtainer \ -p 9000:9 ...