SpringBoot自动配置

  SpringBoot的自动配置是一个运行时(应用程序启动时)的过程,简化开发时间,无需浪费时间讨论具体的Spring配置,只需考虑如何利用SpringBoot的自动配置即可。

  Spring 4.0的条件化配置

  SpringBoot中包含一个spring-boot-autoconfigure的JAR文件,其中包含一应配置类。每个配置类都在应用程序的Classpath里,包括Thymeleaf/Spring Data JPA/Spring MVC等,开发者根据需求选择使用。

  自动配置-设计基础:Spring4.0引入的新特性--条件化配置。条件化配置允许配置存在于应用程序中,但在满足某些特定条件之前都忽略这些配置。

  在Spring里可以很方便地编写自定义的条件,只需要实现Condition接口,覆盖它的matches()方法。

  具体条件化配置使用示例:

/**
* 具体条件类,需实现Condition接口,并重写matchs(.. , ..)方法
*/
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;
}
}
}
---------------------------------------------------------------------
/**
* 声明bean时,使用自定义条件类,作为@Conditional的参数value
*/
@Conditional(JdbcTemplateCondition.class)
public MyService myService(){....}

  在这个例子中,只有当JdbcTemplateCondition类的条件成立时才会创建MyService这个Bean。即MyService Bean创建的条件是Classpath里有JdbcTemplate。否则,这个Bean的声明就会被忽略掉。

  Spring 4.0源码支持:

  @Conditional注解 + Condition接口

/**
* Condition接口,编写自定义条件
*/
public interface Condition {
boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2);
}
---------------------------------------------------------------
/**
* Conditional注解
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
Class<? extends Condition>[] value();
}

  spring-boot-autoconfigure实现分析

  上例相当简单,但SpringBoot定义了很多更有趣的条件,并将其运用到了配置类上,这些配置类构成了SpringBoot的自动配置。SpringBoot运用条件化配置的方法是,定义多个特殊的条件化注解,并将其用到配置类上。

  SpringBoot提供的条件化注解:

自动配置中使用的条件化注解
条件化注解 配置生效条件
@ConditionalOnBean 配置了某个特定Bean
@ConditionalOnMissingBean 没有配置特定的Bean
@ConditionalOnClass Classpath里有指定的类
@ConditionalOnMissingClass Classpath里缺少指定的类
@ConditionalOnExpression 给定的SpEL表达式计算结果为true
@ConditionalOnJava Java的版本匹配特定值或者一个范围值
@ConditionalOnJndi 参数中给定的JNDI位置必须存在一个,如果没有参数,则需要JNDI InitialContext
@ConditionalOnProperty 指定的配置属性要有一个明确的值
@ConditionalOnResource Classpath里有指定的资源
@ConditionalOnWebApplication 这是一个Web应用程序
@ConditionalOnNotWebApplication 这不是一个Web应用程序

  源码剖析,DataSourceAutoConfiguration代码片段:

@Configuration
@ConditionalOnClass({DataSource.class, EmbeddedDatabaseType.class})
@EnableConfigurationProperties({DataSourceProperties.class})
@Import({Registrar.class, DataSourcePoolMetadataProvidersConfiguration.class})
public class DataSourceAutoConfiguration {
    ... ...
  
  @Configuration
  @ConditionalOnProperty(prefix = "spring.datasource", name = "jmx-enabled")
  @ConditionalOnClass(name = "org.apache.tomcat.jdbc.pool.DataSourceProxy")
  @Conditional(DataSourceAutoConfiguration.DataSourceAvailableCondition.class)
  @ConditionalOnMissingBean(name = "dataSourceMBean")
  protected static class TomcatDataSourceJmxConfiguration {
  
  @Bean
  public Object dataSourceMBean(DataSource dataSource) {
   if (dataSource instanceof DataSourceProxy) {
   try {
   return ((DataSourceProxy) dataSource).createPool().getJmxPool();
   }
   catch (SQLException ex) {
   logger.warn("Cannot expose DataSource to JMX (could not connect)");
   }
   }
   return null;
   }   }
    ... ...
}

  分析:DataSourceAutoConfiguration添加了@Configuration注解,它从其他配置类里导入了一些额外配置,本身也定义了一些Bean。最重要的是,DataSourceAutoConfiguration上添加了@ConditionalOnClass注解,要求Classpath中必须要有DataSource和EmbeddedDatabaseType。如果这两个类不存在,条件就不成立,DataSourceAutoConfiguration提供的配置都会被忽略掉。

  DataSourceAutoConfiguration里嵌入了一个 TomcatDataSourceJmxConfiguration 类,自动配置一个 dataSourceMBean Bean。

  TomcatDataSourceJmxConfiguration 使用了@Conditional注解,判断 DataSourceAvailableCondition 条件是否成立——要有一个DataSource Bean或者要自动配置创建一个。

  总结

  SpringBoot利用Spring 4.0提供的条件化配置支持,实现了自动配置。其它应用样例如下:

  1. 因为Classpath里有H2,所以会创建一个嵌入式的H2数据库Bean,类型为javax.sql.DataSource,JPA实现(Hibernate)需要它来访问数据库;
  2. 因为Classpath里有Hibernate(Spring Data JPA传递引入的)的实体管理器,所以自动配置会配置与Hibernate相关的Bean,包括Spring的LocalContainerEntityManagerFactoryBean和JpaVendorAdapter;
  3. 因为Classpath里有SpringDataJPA,所以它会自动配置为根据数据库的接口创建仓库实现;
  4. 因为Classpath里有Thymeleaf,所以Thymeleaf会配置为SpringMVC的视图,包括一个Thymeleaf的模板解析器、模板引擎及视图解析器。视图解析器会解析相对于Classpath根目录的 /templates目录里的模板;
  5. 因为Classpath里有SpringMVC(归功于Web起步依赖),所以会配置Spring的DispatcherServlet并启动SpringMVC;
  6. 因为这是一个Spring MVC Web应用程序,所以会注册一个资源处理器,把相对于Classpath根目录的 /static目录里的静态资源提供出来(还能处理 /public、/resources和 /META-INF/resources的静态内容);
  7. 因为Classpath里有Tomcat,所以会启动一个嵌入式的Tomcat容器,监听8080端口(默认)。

  Spring Boot自动配置承担起了配置Spring的重任,开发者只需专注于自己的应用程序即可。

Spring Boot自动配置与Spring 条件化配置的更多相关文章

  1. Spring Boot 自动装配原理

    Spring Boot 自动装配原理 Spring Boot 在启动之前还有一系列的准备工作,比如:推断 web 应用类型,设置初始化器,设置监听器,启动各种监听器,准备环境,创建 applicati ...

  2. Spring Boot自动配置如何工作

    通过使用Mongo和MySQL DB实现的示例,深入了解Spring Boot的@Conditional注释世界. 在我以前的文章“为什么选择Spring Boot?”中,我们讨论了如何创建Sprin ...

  3. Spring Boot 自动配置的原理、核心注解以及利用自动配置实现了自定义 Starter 组件

    本章内容 自定义属性快速入门 外化配置 自动配置 自定义创建 Starter 组件 摘录:读书是读完这些文字还要好好用心去想想,写书也一样,做任何事也一样 图 2 第二章目录结构图 第 2 章 Spr ...

  4. Springboot 系列(三)Spring Boot 自动配置原理

    注意:本 Spring Boot 系列文章基于 Spring Boot 版本 v2.1.1.RELEASE 进行学习分析,版本不同可能会有细微差别. 前言 关于配置文件可以配置的内容,在 Spring ...

  5. spring boot 自动配置原理

    1).spring boot启动的时候加载主配置类,开启了自动配置功能@EnableAutoConfiguration,先看一下启动类的main方法 public ConfigurableApplic ...

  6. Spring Boot自动配置原理与实践(一)

    前言 Spring Boot众所周知是为了简化Spring的配置,省去XML的复杂化配置(虽然Spring官方推荐也使用Java配置)采用Java+Annotation方式配置.如下几个问题是我刚开始 ...

  7. Spring Boot自动配置原理(转)

    第3章 Spring Boot自动配置原理 3.1 SpringBoot的核心组件模块 首先,我们来简单统计一下SpringBoot核心工程的源码java文件数量: 我们cd到spring-boot- ...

  8. Spring boot --- 自动配置

    spring boot 自动配置 指的是针对很多spring 应用程序常见的应用功能,spring boot 能自动提供相关配置. spring boot 自动配置加载     Spring boot ...

  9. 使用@AutoConfigureBefore、After、Order调整Spring Boot自动配置顺序

    前言 Spring Boot是Spring家族具有划时代意义的一款产品,它发展自Spring Framework却又高于它,这种高于主要表现在其最重要的三大特性,而相较于这三大特性中更为重要的便是Sp ...

随机推荐

  1. 记上海技术交流会之行备忘录(superset与odoo整合)

    像每个早上一样,早起跑步回来冲个热水澡,简单的吃下早饭,看书到8:50的样子,准备赶10:02分的火车.在我看到周总的微信时,我知道这将是一个新的起点,在自己过往的2年时间,将更多的精力和时间用在了英 ...

  2. 有关Web常用字体的研究?

    Windows自带字体: 黑体:SimHei 宋体:SimSun 新宋体:NSimSun 仿宋:FangSong 楷体:KaiTi 仿宋GB2312:FangSongGB2312 楷体GB2312:K ...

  3. 【原创】分布式之elk日志架构的演进

    引言 好久没写分布式系列的文章了,最近刚好有个朋友给我留言,想看这方面的知识.其实这方面的知识,网上各种技术峰会的资料一抓一大把.博主也是凑合着写写.感觉自己也写不出什么新意,大家也凑合看看. 日志系 ...

  4. 从一个例子入门Mysql储存过程

    例子 -- 秒杀执行存储过程 DELIMITER $$ -- 将分隔符; 转换为 $$ -- 定义存储过程 -- 参数: in 输入参数; out 输出参数 -- row_count():返回上一条修 ...

  5. 七、Json格式的对象都可以通过遍历来获得里面的value值

  6. B. Switches and Lamps

    链接 [https://codeforces.com/contest/985/problem/B] 题意 给你n,m,分别是n个开关,m个灯 给一个n*m的字符矩阵aij=1,表示i可以控制j这个灯 ...

  7. NFV组播实验对照

    一 论文题目:Approximation and Online Algorithms for NFV-Enabled Multicasting in SDNs 发表时间:2017 期刊来源:Inter ...

  8. PS制作墙壁上海报卷页图片效果

    1.首先,打开PS,新建合适的画布. 2.为了使背景具有质感,执行滤镜—滤镜库—纹理化,具体参数按你的感觉来. 3.新建画布“图层1”,为了方便观察,填充为灰色画布,ctrl+t适当缩小画布大小,如图 ...

  9. 【转】redis-cluster安装配置

    需要三台虚拟机(生产环境是3个物理机),分配静态IP.cluster中共6个节点.3主3从.本文中每个虚拟机上的redis端口:6379 6380. 需要注意的两点: 3个主节点分别位于3台虚拟机上, ...

  10. 【kindle笔记】之 《浪潮之巅》- 2018-1-

    <浪潮之巅> 这本书推荐自最爱的政治课老师. 政治课老师张巍老师.我会一直记得你的. 以这样的身份来到这个学校,他人的质疑,自己的忐忑,老板的不公.犹犹豫豫谨小慎微地前进. 第一次听到这样 ...