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 {
   ... ...
}
时间: 2024-10-11 17:58:54

Spring Boot . 3 -- Spring Boot Auto_configuration 是如何实现的?的相关文章

spring boot 整合spring Data JPA+Spring Security+Thymeleaf框架(上)

最近上班太忙所以耽搁了给大家分享实战springboot 框架的使用. 下面是spring boot 整合多个框架的使用. 首先是准备工作要做好. 第一  导入框架所需的包,我们用的事maven 进行对包的管理. 以上的举例是本人的H5DS的真实的后台管理项目,这个项目正在盛情融资中,各位多多捧点人场.关注一下软件发展的动态,说不定以后就是您的生活不可或缺的软件哟. 点击打开链接.闲话少说.现在切入正题. 第二,写点配置文件 第三,spring data -设计一个简单的po关系,这里需要下载一

spring、spring MVC、spring Boot

Spring 是一个"引擎" Spring MVC 是基于 Spring 的一个 MVC 框架 Spring Boot 是基于 Spring4 的条件注册的一套快速开发整合包 Spring 最初利用"工厂模式"( DI )和"代理模式"( AOP )解耦应用组件 Spring 框架是一个分层架构,由 7 个定义良好的模块组成. Spring 模块构建在核心容器之上,核心容器定义了创建.配置和管理 bean 的方式:组成 Spring 框架的每个模

【spring Boot】Spring中@Controller和@RestController之间的区别

spring Boot入手的第一天,看到例子中的@RestController ............. 相同点:都是用来表示Spring某个类的是否可以接收HTTP请求 不同点:@Controller标识一个Spring类是Spring MVC controller处理器 @RestController:  a convenience annotation that does nothing more than adding the@Controller and @ResponseBody 

《02.Spring Boot连载:Spring Boot实战.Spring Boot核心原理剖析》

在上节中我们通过了一个小的入门案例已经看到了Spring Boot的强大和简单之处.本章将详细介绍Spring Boot的核心注解,基本配置和运行机制.笔者一直认为:精通一个技术一定要深入了解这个技术帮助我们做了哪些动作,深入理解它底层的运行原理,只有达到这个目标才可以熟练使用框架,最终达到融会贯通的目的. 一.启动类与@SpringBootApplication Spring Boot的项目一般都会有注解*Application标注的入口类,入口类中会有一个main方法,main方法是一个标准

spring boot 中Spring data jpa数据库表字段命名策略

spring boot 中Spring data jpa命名策略 数据库,表字段命名是驼峰命名法(UserID),Spring data jpa 自动更新之后是 user_id, 表字段不对照, Spring data jpa基于Hibernate5.0 application.properties 写法 1.无修改命名 spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNa

漫谈spring cloud 与 spring boot 基础架构

详情请交流  QQ  709639943 01.漫谈spring cloud 与 spring boot 基础架构 02.漫谈spring cloud分布式服务架构 03.Node.js入门到企业Web开发中的应用 04.精通高级RxJava 2响应式编程思想 05.Java秒杀系统方案优化 高性能高并发实战 06.Java深入微服务原理改造房产销售平台 07.快速上手Linux 玩转典型应用 08.快速上手Ionic3 多平台开发企业级问答社区 09.Java Spring Security开

spring boot与spring mvc的区别是什么?

Spring 框架就像一个家族,有众多衍生产品例如 boot.security.jpa等等.但他们的基础都是Spring 的 ioc和 aop ioc 提供了依赖注入的容器 aop ,解决了面向横切面的编程,然后在此两者的基础上实现了其他延伸产品的高级功能.Spring MVC是基于 Servlet 的一个 MVC 框架 主要解决 WEB 开发的问题,因为 Spring 的配置非常复杂,各种XML. JavaConfig.hin处理起来比较繁琐.于是为了简化开发者的使用,从而创造性地推出了Spr

eclipse安装spring boot插件spring tool suite

进行spring cloud的学习,要安装spring boot 的spring -tool-suite插件,我在第一次安装时,由于操作不当,两天才完全安装好,真的是要命了,感觉自己蠢死!下面就自己踩过坑以及一些小窍门和大家分享一下. 安装方法:(我使用的是eclipse ,所以就拿eclipse举例了) 提示:安装时,网速不好的话过程会比较漫长,所以最好是选择一个网络好一点的地方进行安装. 方法1.可以自己在eclipse目录:help-->Eclipse Marketplace 下的Sear

Spring Kafka和Spring Boot整合实现消息发送与消费简单案例

本文主要分享下Spring Boot和Spring Kafka如何配置整合,实现发送和接收来自Spring Kafka的消息. 先前我已经分享了Kafka的基本介绍与集群环境搭建方法.关于Kafka的介绍请阅读Apache Kafka简介与安装(一),关于Kafka安装请阅读Apache Kafka安装,关于Kafka集群环境搭建请阅读Apache Kafka集群环境搭建 .这里关于服务器环境搭建不在赘述. Spring Kafka整合Spring Boot创建生产者客户端案例 创建一个kafk

深入浅出,了解 Spring 框架和 Spring Boot 的历史

Spring 框架可以说是 Java 开发人员使用的最流行的应用程序开发框架之一.它目前由大量提供一系列服务的模块组成.包括模块容器,为构建横切关注点提供支持的面向切面编程(AOP),安全框架,数据存取框架,Web 应用框架和用于模块测试提供支持的类.Spring 框架的所有组件都通过依赖注入粘在一起.依赖注入(也称为控制反转)使设计和测试松散耦合的软件模块变得更容易. 多年来 Spring 框架已变得足够成熟.几乎所有 Java 企业应用需要用到的基础组件都可以在 Spring 框架中找到.但