概 述

SpringBoot 约定大于配置 的功力让我们如沐春风,在我之前写的文章《从SpringBoot到SpringMVC》
也对比过 SpringBoot 和 SpringMVC 这两个框架,不过最终 SpringBoot 以超高的代码信噪比 和 易上手性 让我们映像颇深。

但归根结底,不论 SpringBoot 或者 SpringMVC 应用本质上依然是一个基于 Spring的应用,只不过在后者脸庞上蒙上了一层神秘的面纱而已!

回到 SpringBoot 的话题,我们在开发基于 SpringBoot 的应用时,用到了一些新的注解和类,正式由于其存在,才让JavaEE的开发如鱼得水。这其中我们用的最多的注解之一,当属 SpringBoot 应用启动类上的 @SpringBootApplication 注解了

本文就来看看它到底是个啥!



@SpringBootApplication 背后到底是什么?

@SpringBootApplication注解实际上是SpringBoot提供的一个复合注解,我们来看一看其源码:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
...
}

看得很清楚,其是一个合成体,但其中最重要的三个注解分别是:

  • @SpringBootConfiguration

  • @EnableAutoConfiguration

  • @ComponentScan

我们不妨称其为 “ 三体结构 ” 吧!

如果我们不怕麻烦,在 SpringBoot 应用的启动类上用这个三个注解代替@SpringBootApplication 注解发现也是没问题的:

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public class TestSpringBootApplication {
...
}

下面分别剖析一下这三个注解的功效!



@SpringBootConfiguration

看代码吧,代码里是这样写的:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration { }

这说明 @SpringBootConfiguration 也是来源于 @Configuration,二者功能都是将当前类标注为配置类,并将当前类里以 @Bean 注解标记的方法的实例注入到srping容器中,实例名即为方法名。

至于@Configuration,我想在非SpringBoot时代大家应该不陌生吧,作用是配置Spring容器,也即 JavaConfig 形式的 Spring IoC 容器的配置类所使用。

到目前来看,好像还没有什么新东西!!!



@EnableAutoConfiguration

再继续看代码,代码是这样的:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
...
}

@EnableAutoConfiguration 注解启用自动配置,其可以帮助 SpringBoot 应用将所有符合条件的 @Configuration 配置都加载到当前 IoC 容器之中,可以简要用图形示意如下:

 
@EnableAutoConfiguration 幕后的组件调用关系

接下来我们对照源码,来解释一下这个流程:

  • @EnableAutoConfiguration 借助 AutoConfigurationImportSelector 的帮助,而后者通过实现 selectImports() 方法来导出 Configuration
 
selectImports()
  • AutoConfigurationImportSelector 类的 selectImports() 方法里面通过调用Spring Core 包里 SpringFactoriesLoader 类的 loadFactoryNames()方法
 
SpringFactoriesLoader.loadFactoryNames()
  • 最终通过 SpringFactoriesLoader.loadFactoryNames() 读取了 ClassPath 下面的 META-INF/spring.factories 文件来获取所有导出类。

而spring.factories 文件里关于 EnableAutoConfiguration 的配置其实就是一个键值对结构,样子大概长下面这样:

 
spring.factories

说了这么多,如果从稍微宏观一点的角度 概括总结 上述这一过程那就是:

从 ClassPath下扫描所有的 META-INF/spring.factories 配置文件,并将spring.factories 文件中的 EnableAutoConfiguration 对应的配置项通过反射机制实例化为对应标注了 @Configuration 的形式的IoC容器配置类,然后注入IoC容器。



@ComponentScan

@ComponentScan 对应于XML配置形式中的 <context:component-scan>,用于将一些标注了特定注解的bean定义批量采集注册到Spring的IoC容器之中,这些特定的注解大致包括:

  • @Controller
  • @Entity
  • @Component
  • @Service
  • @Repository

等等

对于该注解,还可以通过 basePackages 属性来更细粒度的控制该注解的自动扫描范围,比如:

@ComponentScan(basePackages = {"cn.codesheep.controller","cn.codesheep.entity"})

可见 这个注解也并不是什么新东西!

Spring Boot 中 @SpringBootApplication注解背后的三体结构探秘的更多相关文章

  1. (32)Spring Boot使用@SpringBootApplication注解,从零开始学Spring Boot

    [来也匆匆,去也匆匆,在此留下您的脚印吧,转发点赞评论] 如果看了我之前的文章,这个节你就可以忽略了,这个是针对一些刚入门的选手存在的困惑进行写的一篇文章. 很多Spring Boot开发者总是使用 ...

  2. spring boot 中@Autowired注解无法自动注入的错误

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/huihuilovei/article/de ...

  3. Spring Boot中@Scheduled注解的使用方法

    Spring Boot中@Scheduled注解的使用方法 一.定时任务注解为@Scheduled,使用方式举例如下 //定义一个按时间执行的定时任务,在每天16:00执行一次. @Scheduled ...

  4. Spring Boot中的注解

    文章来源:http://www.tuicool.com/articles/bQnMra 在Spring Boot中几乎可以完全弃用xml配置文件,本文的主题是分析常用的注解. Spring最开始是为了 ...

  5. Spring Boot中自定义注解+AOP实现主备库切换

    摘要: 本篇文章的场景是做调度中心和监控中心时的需求,后端使用TDDL实现分表分库,需求:实现关键业务的查询监控,当用Mybatis查询数据时需要从主库切换到备库或者直接连到备库上查询,从而减小主库的 ...

  6. Spring Boot中@ConfigurationProperties注解实现原理源码解析

    0. 开源项目推荐 Pepper Metrics是我与同事开发的一个开源工具(https://github.com/zrbcool/pepper-metrics),其通过收集jedis/mybatis ...

  7. 56. spring boot中使用@Async实现异步调用【从零开始学Spring Boot】

    什么是"异步调用"? "异步调用"对应的是"同步调用",同步调用指程序按照定义顺序依次执行,每一行程序都必须等待上一行程序执行完成之后才能执 ...

  8. 46. Spring Boot中使用AOP统一处理Web请求日志

    在之前一系列的文章中都是提供了全部的代码,在之后的文章中就提供核心的代码进行讲解.有什么问题大家可以给我留言或者加我QQ,进行咨询. AOP为Aspect Oriented Programming的缩 ...

  9. Spring Boot中的缓存支持(一)注解配置与EhCache使用

    Spring Boot中的缓存支持(一)注解配置与EhCache使用 随着时间的积累,应用的使用用户不断增加,数据规模也越来越大,往往数据库查询操作会成为影响用户使用体验的瓶颈,此时使用缓存往往是解决 ...

随机推荐

  1. 安卓SDK的配置流程以及安装build-tools等插件

    这两天做了一个移动端混合开发的项目,需要配置安卓的SDK,不过在这之前,需要先配置好Java环境(这个在这里就不写了).下面开始配置步骤: 1.下载SDK,然后解压到某个目录下面.推荐两个下载网址: ...

  2. codelite配置信息

    codelite下编译执行wxwidgets库需要修改链接库如下: 原来的c++ compiler配置-g;-O0;-Wall;$(shell wx-config --cflags --debug) ...

  3. 转载:java面试题(一)

    1.面向对象的特征有哪些方面? 答:面向对象的特征主要有以下几个方面: - 抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面.抽象只关注对象有哪些属性和行为,并不关注 ...

  4. JSP自定义方法标签

    1.自定义方法标签 引入方式示例: <%@ taglib prefix="fns" uri="/WEB-INF/tlds/fns.tld" %> 写 ...

  5. 牛客挑战赛33 F 淳平的形态形成场(无向图计数,EGF,多项式求逆)

    传送门: 淳平的形态形成场 题解: 把a排序后,直接统计答案恰好为a[i]并不好做,可以统计答案>a[i]的方案数,设为\(f[i]\). 即不存在一个联通块,所有的权值都<=a[i]. ...

  6. eureka学习(一)

    eureka是一个注册中心,与zookeeper不同的是,eureka是restful格式的调用,zk是rpc,还有就是zk保证一致和容错,eureka则是可用和容错. 使用时首先要加入依赖 < ...

  7. Kubernetes v1.16 对API的更改

    前段时间安装Kubernetes v1.16.2,然后从v1.14版本的拷贝yaml文件过来执行,很多都报没有相应的api,查看一下新版本的api admissionregistration.k8s. ...

  8. CDN技术详解(七)

    动态内容加速服务的实现 随着Web2.0的兴起,产生了动态网页.个性化内容.电子交易数据等内容的加速,这些就涉及了动态内容加速技术. 静态内容的加速,都是对于表现层的加速,对于动态页面等内容的加速,则 ...

  9. 前端每日实战:73# 视频演示如何用纯 CSS 创作一只卡通狐狸

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/OEKZed 可交互视频 此视频是可 ...

  10. XAMPP安装和配置

    一.XAMPP安装: 下载地址:https://www.apachefriends.org/zh_cn/index.html 二.修改MySQL数据库 1.更改Apache中数据库端口号 保存后重新启 ...