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是一个轻量级的企业开发框架,主要功能就是用于整合和管理其他框架,想法是将平时主流使用到的框架的整合配置预先写好,然后通过 ...
随机推荐
- 洛谷P4136 谁能赢呢?——博弈
题目:https://www.luogu.org/problemnew/show/P4136 每个人有足够聪明,一定会把图走满: 所以n为偶数先手胜,n为奇数后手胜. 代码如下: #include&l ...
- bzoj3251
3251: 树上三角形 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 637 Solved: 262[Submit][Status][Discuss ...
- 3.ExtJs常用布局--layout详解(含实例)
转自:https://blog.csdn.net/fifteen718/article/details/51482826
- 不让浏览器缓存input的值
方法一: 在不想使用缓存的input中添加 autocomplete="off"eg: <input type="text" autocomplete=& ...
- 线程Coroutines 和 Yield(转)
之前一直很纠结这个问题,在网上找到了这篇文章,给大家分享下: 第一种方法: void Start() { print("Starting " + Ti ...
- Android Studio编写运行测试纯java代码可带main()函数
问题 小伙伴们在做安卓项目的时候,是不是有时候会忘记某些api的使用方法,不太确定他们的结果是怎样的,需要写一些测试代码,验证看看我们的写法是否正确.刚开始的时候我是在页面上写一个Button,添加点 ...
- MoveTo和LineTo函数的意思
这是个画线函数, moveto是移动到某个坐标,lineto是从当前坐标, 移动的某个坐标连接早当前坐标.这两个函数加起来就是画一条直线.
- 题解报告:hdu 4907 Task schedule
Problem Description 有一台机器,并且给你这台机器的工作表,工作表上有n个任务,机器在ti时间执行第i个任务,1秒即可完成1个任务.有m个询问,每个询问有一个数字q,表示如果在q时间 ...
- ACM_数数?诶?这么简单?
数数?诶?这么简单? Time Limit: 2000/1000ms (Java/Others) Problem Description: 当看到GDUFE-GAME宣传海报上提到"场内人员 ...
- 如何隐藏electron窗体的菜单栏
electron中默认带有顶部菜单栏,有时候我们的应用不需要. 再main.js文件中设置 const electron = require('electron') const path = requ ...