Spring Boot . 3 -- Spring Boot Auto_configuration 是如何实现的?
配置是Spring 框架的重要核心之一,所以Spring 应用能够正常的跑起来肯定是需要配置的,但是使用的Spring Boot 后很多配置没有做,那么AUTO-CONFIGURATION 到底是怎么发生的呢?发生的顺序和步骤是怎样的?怎么实现的呢?
在应用中使用Spring Boot的时候,spring-boot-autoconfigure这个jar包会被引入进来,这个Jar包里面包含了一些配置类。这个包里的所有都在应用的claspath上,都有可能在自动配置执行的过程中被用到,从而简化应用的配置工作。这个jar的内容大致是下面这个样子:

箭头指向的基本在ReadingList应用中都有用到,这些配置类通过注解的方式使用,在运行期通过一系列的条件判断进行Bean的加载和配置。在这些配置完成后,一个可用的应用运行环境就准备好了。实现这些配置类的基础是Spring 4.0 提供的Condition 接口,通过实现Condition 接口的matches 方法来进行动态的判定。先来看看Condition 接口怎么用。
1. Spring 4.0 开始提供的 Condition 接口。
举个例子。需要在应用中建立一个操作数据库的DBService 类,这个类中要用到JdbcTemplate的实例。那么实例化JdbcTemplate前,首先要保证JdbcTemplate 在应用的classpath上,那怎么判断classpath上是不是有JdbcTemplate?用Condition 接口怎么实现这个判断呢?
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata; public class JdbcTemplateCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
try {
context.getClassLoader().loadClass("org.springframework.jdbc.core.JdbcTemplate");
return true;
} catch (Exception e) {
return false;
}
}
}
这个判断实现完成,如何使用这个判断条件呢?
@Conditional(JdbcTemplateCondition.class)
public DBService dbService() {
@AutoWire
JdbcTemplate jdbcTemplate; // TODO
}
DBService 在实例化以前首先要判断 JdbcTemplateCondition,返回true才会继续进行实例化,否则当前的类会被忽略,不进行实例化。
2、Spring Boot 实现的Conditional** 形式的注解。
Spring Boot 实现了一系列的Conditional Annotation。这些基本上是可以见名知意的。下面就是一部分常见的条件注解(Conditional Annotation)。

没有不要去看所有的条件注解的具体实现,但是为了能够比较明晰的解释Auto-Configuration 的工作过程,将 DataSourceAutoConfiguration 的具体实现写一下,加深下自动配置的理解,也可以学习使用 @Conditional 注解和 接口Condition 的使用。
@Configuration
@ConditionalOnClass({DataSource.class, EmbeddedDatabaseType.class})
@EnableConfigurationProperties({DataSourceProperties.class})
@Import({Registrar.class, DataSourcePoolMetadataProvidersConfiguration.class})
public class DataSourceAutoConfiguration {
... ...
}
1、第一个注解 @Configuration 这个和xml 配置Bean 是同样的效果,这个就不详细解释了。
2、第二个注解 @ConditionalOnClass 的意思:在classpath 在上有相应的类的话 返回True,否则返回false。
3、第三个注解 @EnableConfigurationProperties({DataSourceProperties.class}) 允许使用application.properties 文件配置 DataSource 的参数。
4、第四个注解 @Import 将其参数中的类引入并初始化为一个Bean。
真正要关注的是第二个注解 ConditionalOnClass,这个注解判断 DataSource 和 EmbededDataBaseType 两个类是否在classpath 上。如果此条件判定为真,开始后续的判定。继而判断当前是否有DataSource 实例,是否是嵌入式的数据,是否有嵌入式的Tomcat 等等。。一些列运行时判定最终决定是否生成配置一个可用的数据源。
3、ReadingList 工程中 Auto-Configuration 工作的过程。
(1)因为H2在classpath上,因此一个嵌入式的H2 数据库被实例化,这个Bean 是 javax.sql.DataSource 类型的,所以 一个JPA 的接口需要实例化。
(2)因为 Hibernate Entity Manager 在classpath上,因此启用Hibernate的话,需要auto-configuration 需要实例化 LocalContainerManagerFactory Bean 和 JPAVendorAdapter。
(3)因为 JPA 在 classpath 上,所以repository 的实例也会被自动创建。
(4)因为Spring MVC 在classpath上, Spring 的DispatcherServlet 会被实例化。
(5)因为是web 应用,因此一个资源的handler 会被注册,来处理 resource 目录下的静态资源。
(6)因为Tomcat 在classpath 上,一个内置的Tomcat 容器会被启动承载和提供服务。
4、其实不知道也不影响用Spring Boot 实现业务嘛。
这一篇不写也罢。
举个用Condition 的例子:
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
// 如果在applicaton.properties 文件中 见env.test=1 那么对应的类会被加载
@ConfigurationProperties("env.test")
public class TestEnableCondition implements Condition { public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
String test = conditionContext.getEnvironment().getProperty("env.test");
int isTest;
try {
isTest = Integer.valueOf(test);
} catch (Exception e) {
isTest = 0;
}
return isTest==1;
}
}
@Conditional(TestEnableCondition.class)
@Controller
@RequestMapping(value = "/{param}")
public class TestController {
... ...
}
Spring Boot . 3 -- Spring Boot Auto_configuration 是如何实现的?的更多相关文章
- 一:Spring Boot、Spring Cloud
上次写了一篇文章叫Spring Cloud在国内中小型公司能用起来吗?介绍了Spring Cloud是否能在中小公司使用起来,这篇文章是它的姊妹篇.其实我们在这条路上已经走了一年多,从16年初到现在. ...
- Spring Kafka和Spring Boot整合实现消息发送与消费简单案例
本文主要分享下Spring Boot和Spring Kafka如何配置整合,实现发送和接收来自Spring Kafka的消息. 先前我已经分享了Kafka的基本介绍与集群环境搭建方法.关于Kafka的 ...
- 使用Spring Session实现Spring Boot水平扩展
小编说:本文使用Spring Session实现了Spring Boot水平扩展,每个Spring Boot应用与其他水平扩展的Spring Boot一样,都能处理用户请求.如果宕机,Nginx会将请 ...
- 一起来学spring Cloud | 第一章:spring Cloud 与Spring Boot
目前大家都在说微服务,其实微服务不是一个名字,是一个架构的概念,大家现在使用的基于RPC框架(dubbo.thrift等)架构其实也能算作一种微服务架构. 目前越来越多的公司开始使用微服务架构,所以在 ...
- Spring,Spring MVC及Spring Boot区别
什么是Spring?它解决了什么问题? 我们说到Spring,一般指代的是Spring Framework,它是一个开源的应用程序框架,提供了一个简易的开发方式,通过这种开发方式,将避免那些可能致使代 ...
- 基于Spring Boot、Spring Cloud、Docker的微服务系统架构实践
由于最近公司业务需要,需要搭建基于Spring Cloud的微服务系统.遍访各大搜索引擎,发现国内资料少之又少,也难怪,国内Dubbo正统治着天下.但是,一个技术总有它的瓶颈,Dubbo也有它捉襟见肘 ...
- Spring Cloud Alibaba与Spring Boot、Spring Cloud之间不得不说的版本关系
这篇博文是临时增加出来的内容,主要是由于最近连载<Spring Cloud Alibaba基础教程>系列的时候,碰到读者咨询的大量问题中存在一个比较普遍的问题:版本的选择.其实这类问题,在 ...
- Spring Cloud和Spring Boot的区别
Spring MVC: Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 Web 应用程序的全功能 MVC ...
- maven 聚合工程 用spring boot 搭建 spring cloud 微服务 模块式开发项目
项目的简单介绍: 项目采用maven聚合工程 用spring boot 搭建 spring cloud的微服务 模块式开发 项目的截图: 搭建开始: 能上图 我少打字 1.首先搭建maven的聚合工程 ...
- Spring Boot(Spring的自动整合框架)
Spring Boot 是一套基于Spring框架的微服务框架,由于Spring是一个轻量级的企业开发框架,主要功能就是用于整合和管理其他框架,想法是将平时主流使用到的框架的整合配置预先写好,然后通过 ...
随机推荐
- hdu 2553(N皇后问题)
N皇后问题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- css content
before after demo 1 添加描述信息 div1:after{conent:"天假额外的文字"} 2 也可以显示元素的某些属性 <a class="d ...
- hdu1530 求最大团
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1530 求最大团裸题. 模板:maxx即为所求的最大团的值. #include<iostream& ...
- bzoj 1499: [NOI2005]瑰丽华尔兹【dp+单调队列】
设f[a][i][j]为第a段时间结束时在(i,j)位置的最长滑行距离,转移很好想,就是分四个方向讨论,然后枚举这段时间的滑行长度取个max即可 但是这样是O(n^4)的,考虑优化 发现同一行或列,取 ...
- js下传递的时间用strtotime()函数解析差8小时
php 日期转时间戳: $time = $_POST["time"];$time = strtotime($time)-8*3600; php 时间戳转日期: date_defa ...
- Unix\Linux | 总结笔记 |文件系统
1. ls [选项] [文件] 显示目录中的文件信息 -a 显示全部文件(包括隐藏文件) -l 查看文件的属性.大小等详细信息 (ls -l 详解) -al 查看当前目录中 ...
- python3 写CSV文件多一个空行的解决办法
Python文档中有提到: open('eggs.csv', newline='') 也就是说,打开文件的时候多指定一个参数.Python文档中也有这样的示例: import csvwith open ...
- _bzoj1087 [SCOI2005]互不侵犯King【dp】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1087 令f(i, j, k)表示前i列,二进制状态为j,已经用了k个国王的方案数,则 f(i ...
- linux知识目录
linux 知识目录 linux 前台后台程序切换命令总结 shell脚本从入门到精通 Ubuntu下如何用命令运行deb安装包 <linux就该这么学>学习笔记
- android:process用法
1.作用 android:process将组件在新进程中运行. 2.应用范围 可以出现在<application> <activity>, <service>, ...