AI 助理
备案 控制台
开发者社区 开发与运维 文章 正文

Spring Boot核心原理实现及核心注解类

简介: Spring Boot核心原理实现及核心注解类

Spring Boot最核心的功能就是“自动配置”,这一切都基于“约定优于配置”的原则。那么Spring Boot是如何约定,又是如何实现自动配置功能的呢?下面带大家来通过源码学习Spring Boot的核心运作原理以及最核心的注解@EnableAutoConfiguration来进行讲解。



1.1核心运行原理

使用Spring Boot时我们只需引入对应的Starters,Spring Boot启动时便自会动加载相关依赖,配置相应的初始化参数,以最快捷、简单的形式对第三方软件进行集成,这便是Spring Boot的自动配置功能。先从整体上看一下Spring Boot实现该运作机制涉及到的核心部分,如图2-1。image.png图中描述了Spring Boot自动配置运作过程中涉及的几个核心功能及其相互之间的关系。

它们包括:@EnableAutoConfiguration、spring.factories、各组件对应的AutoConfiguration类、@Conditional注解以及各种Starters。

如果用一句话来描述整个过程就是:Spring Boot通过@EnableAutoConfiguration注解开启自动配置,加载spring.factories中注册的各种AutoConfiguration类,当某个AutoConfiguration类满足其注解@Conditional指定的生效条件(Starters提供的依赖、配置或Spring容器中是否存在某个Bean等)时,那么实例化该AutoConfiguration类中定义的Bean(组件等),并注入Spring容器,至此就完成了依赖框架的自动配置。

先从概念及功能上了解一下上图所属部分的作用及相互关系,后面章节会针对每个功能及组件进行源代码级别的讲解。@EnableAutoConfiguration:该注解由组合注解@SpringBootApplication引入,完成自动配置开启,扫描各个jar包下的spring.factories文件,并加载其中注册的AutoConfiguration类等。

spring.factories:配置文件,位于jar包的META-INF目录下,按照指定格式注册了自动配置的AutoConfiguration类,也可以包含其他类型待注册的类。该配置文件不仅存在于Spring Boot项目中,也可以存在于自定义的自动配置(或Starter)项目中。

AutoConfiguration类:自动配置类,代表了Spring Boot中一类以XXAutoConfiguration命名的自动配置类。其中定义了三方组件集成Spring所需初始化的Bean和条件。

@Conditional:条件注解及其衍生注解,使用在AutoConfiguration类上,当满足该条件注解时才会实例化AutoConfiguration类。

Starters:三方组件的依赖及配置,Spring Boot已经预置的组件。Spring Boot默认的Starters项目往往是只包含了一个pom依赖的项目。如果自定义的starter,该项目还需包含spring.factories文件、AutoConfiguration类和其他配置类。

以上在概念层面了解了Spring Boot自动配置的整体流程和基本运作原理,下面重点看一下@EnableAutoConfiguration注解的功能。



1.2运作原理源码解析之

@EnableAutoConfiguration

@EnableAutoConfiguration是开启自动配置的注解,在创建的Spring Boot项目中并不能直接看到此注解,它是由组合注解@SpringBootApplication引入。下面,我们首先了解一下入口类和@SpringBootApplication注解,然后再深入了解@EnableAutoConfiguration注解的构成与作用。



1.2.1入口类和

@SpringBootApplication注解

Spring Boot项目创建完成会默认生成一个*Application的入口类。默认情况下,无论通过IDEA或通过官网创建基于Maven的Spring Boot项目,入口类的命名规则为:artifactId+Application。通过该类的main方法即可启动Spring Boot项目。


@SpringBootApplication
public class SpringLearnApplication {
 public static void main(String[] args) {
      SpringApplication.run(DemoApplication.class, args);
   }
}


关于main方法并无特别之处,就是一个标准的Java应用的main方法,这里是启动Spring Boot项目的入口。默认情况下,按照上述命名规则并包含main方法的类,我们以下称作“入口类”。在入口类中,我们可以看到Spring Boot创建的代码中(除单元测试外)唯一的一个注解就是@SpringBootApplication。它是Spring Boot项目的核心注解,用于开启自动配置,准确说是该注解内组合的@EnableAutoConfiguration开启了自动配置。@SpringBootApplication部分源代码如下:


@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 {
   // 排除指定自动配置类
   @AliasFor(annotation = EnableAutoConfiguration.class)
   Class<?>[] exclude() default {};
// 排除指定自动配置类名
   @AliasFor(annotation = EnableAutoConfiguration.class)
   String[] excludeName() default {};
// 指定扫描的基础包,激活注解组件的初始化
   @AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
   String[] scanBasePackages() default {};
// 指定扫描的类,用于初始化
   @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
   Class<?>[] scanBasePackageClasses() default {};
// 指定是否代理@Bean方法以强制执行bean的声明周期行为。
@AliasFor(annotation = Configuration.class)
boolean proxyBeanMethods() default true;
}


通过源代码可以看出,该注解提供了以下成员属性(注解中的成员变量以方法的形式体现):exclude:根据类(Class)排除指定的自动配置,该成员属性覆盖了@SpringBootApplication 中组合的@EnableAutoConfiguration中定义的exclude成员属性。

excludeName:根据类名排除指定的自动配置,同样覆盖了@EnableAutoConfiguration中的excludeName的成员属性。

scanBasePackages:指定扫描的基础package,用于激活@Component等注解类的初始化。

scanBasePackageClasses:扫描指定的类,用于组件的初始化。

proxyBeanMethods:指定是否代理@Bean方法以强制执行bean的声明周期行为。此功能需要通过运行时生成CGLIB子类来实现方法拦截,该子类有一定的限制,比如配置类及其方法不允许声明为final等。默认值为true,允许配置类中进行“inter-bean references”(bean之间的引用)以及对该配置的@Bean方法的外部调用。如果@Bean方法都是自包含的,并且仅提供了容器使用的普通工程方法的功能,则可设置为false,避免处理CGLIB子类。Spring Boot 2.2新增该成员属性,后面章节涉及到的自动配置类中基本都会使用,一般情况下都配置为false。

以上源代码会发现,大量使用了@AliasFor注解,该注解用于桥接到其他注解,该注解的属性中指定了所桥接的注解类。如果点进去查看,会发现@SpringBootApplication定义的属性,在其他注解中已经定义过了。之所以使用@AliasFor注解并重新在@SpringBootApplication中定义,更多的意义是为了减少用户使用多注解带来的麻烦。@SpringBootApplication注解中组合了@SpringBootConfiguration、@EnableAutoConfiguration和@ComponentScan。因此,在实践过程中也可以使用这三个注解来替代@SpringBootApplication。在早期版本中并没有@SpringBootConfiguration注解,后新增了@SpringBootConfiguration并在其内组合了@Configuration。@EnableAutoConfiguration注解组合了@AutoConfigurationPackage。忽略掉一些基础注解和元注解,@SpringBootApplication注解的组合结构可以参考图2-2。


image.png


在上图中,@SpringBootApplication除了组合元注解之外,核心包括:用于激活Spring Boot自动配置的@EnableAutoConfiguration、用于激活@Component扫描的@ComponentScan、用于激活配置类的@Configuration。其@ComponentScan注解和@Configuration注解在Spring的日常使用中经常用到,不再赘述,而关于@EnableAutoConfiguration正是我们下面要详细介绍的。




1.2.2注解@EnableAutoConfiguration

功能解析

在未使用Spring Boot的情况下,Bean的生命周期由Spring来管理,然而Spring无法自动配置@Configuration注解的类。而Spring Boot所做的核心之一就是根据约定可以自动化的管理该注解标注的类。用来实现该功能的组件之一便是@EnableAutoConfiguration注解。

@EnableAutoConfiguration位于spring-boot-autoconfigure包内,当使用@SpringBootApplication注解时,该注解会自动生效。

@EnableAutoConfiguration的主要功能是启动Spring应用程序上下文时进行自动配置,它会尝试猜测并配置你可能需要的Bean。自动配置通常是基于项目classpath中引入的类和已定义的Bean来实现的。在此过程中,被自动配置的组件来自项目自身和项目依赖的jar包中。


举个例子:如果将tomcat-embedded.jar添加到classpath下,那么@EnableAutoConfiguration会认为你准备使用TomcatServletWebServerFactory类,并帮你初始化相关配置。与此同时如果自定义了基于ServletWebServerFactory的Bean,那么,它将不会进行TomcatServletWebServerFactory类的初始化。这一系列的操作判断,都由Spring Boot来完成。


下面我们来看一下@EnableAutoConfiguration注解的源代码:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
// 用来覆盖配置来开启/关闭自动配置的功能
   String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
// 根据类(Class)排除指定的自动配置
   Class<?>[] exclude() default {};
// 根据类名排除指定的自动配置
   String[] excludeName() default {};
}


该注解提供了一个常量和两个成员参数的定义:

ENABLED_OVERRIDE_PROPERTY:可以用来覆盖配置来开启/关闭自动配置的功能。


exclude:根据类(Class)排除指定的自动配置


excludeName:根据类名排除指定的自动配置。

正如上面所说,@EnableAutoConfiguration会猜测你所需要使用的Bean,但如果在实战中你并不需要它预置初始化的Bean,则可通过该注解的exclude或excludeName参数来进行有针对性的排除。

比如,当不需要数据库的自动配置时,可通过以下两种方式让其自动配置失效:

// 通过@SpringBootApplication排除DataSourceAutoConfiguration
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class) 
public class SpringLearnApplication {
}

或:

// 通过@EnableAutoConfiguration排除DataSourceAutoConfiguration
@Configuration
@EnableAutoConfiguration(exclude = DataSourceAutoConfiguration.class)
public class DemoConfiguration {
}


需要注意的是,被@EnableAutoConfiguration注解的类所在package还具有特定的意义,通常会被作为扫描注解@Entity的根路径。这也是为什么在使用@SpringBootApplication注解时需要将被注解的类放在顶级package下的原因,如果放在较低层级,则它所在package的同级或上级中的类则无法被扫描到。

而对于入口类和其main方法来说,并不依赖@SpringBootApplication注解或@EnableAutoConfiguration,也就是说该注解可以使用在其他类上,而非入口类上,同样生效。



1.3 AutoConfigurationImportSelector源码解析

@EnableAutoConfiguration的关键功能是通过@Import注解导入的ImportSelector来完成的。从源码得知@Import(AutoConfigurationImportSelector.class)是@EnableAutoConfiguration注解的组成部分,也是自动配置功能的核心实现者。它又可以分为两部分:@Import和对应的ImportSelector。本节重点讲解@Import的基本使用和ImportSelector的实现类AutoConfigurationImportSelector。



1.3.3.AutoConfigurationImportSelector功能概述

下面,通过一张流程图来从整体上了解AutoConfigurationImportSelector功能及流程图。

图中省略了外部通过@Import注解调用该类的部分。image.png当AutoConfigurationImportSelector被@Import注解引入之后,它的selectImports方法会被调用并执行其实现的自动装配逻辑。读者朋友需注意的selectImports方法几乎涵盖了组件自动装配的所有处理逻辑。通过上图从整体上了解了AutoConfigurationImportSelector的概况及操作流程,关于AutoConfigurationImportSelector的详细实现可参考Spring Boot中的源码进行逐步分析,本篇文章就不再进行过多拓展。



1.4小结

本篇文章围绕Spring Boot的核心功能展开,带大家从总整体上了解Spring Boot自动配置的原理以及自动配置核心组件的运作过程。只有掌握了这些基础的组建及其功能,在后续集成其他三方类库的自动配置时才能够更加清晰的了解它们都运用了自动配置的哪些功能。

longfor5
目录
相关文章
猿java
|
12天前
|
Java Spring 容器
如何解决spring EL注解@Value获取值为null的问题
本文探讨了在使用Spring框架时,如何避免`@Value(&quot;${xxx.xxx}&quot;)`注解导致值为null的问题。通过具体示例分析了几种常见错误场景,包括类未交给Spring管理、字段被`static`或`final`修饰以及通过`new`而非依赖注入创建对象等,提出了相应的解决方案,并强调了理解框架原理的重要性。
猿java
50 4
石小浪♪
|
9天前
|
XML Java 数据格式
Spring从入门到入土(bean的一些子标签及注解的使用)
本文详细介绍了Spring框架中Bean的创建和使用,包括使用XML配置文件中的标签和注解来创建和管理Bean,以及如何通过构造器、Setter方法和属性注入来配置Bean。
石小浪♪
44 9
Spring从入门到入土(bean的一些子标签及注解的使用)
游客r43put2rqnbp4
|
2天前
|
架构师 Java 开发者
得物面试:Springboot自动装配机制是什么?如何控制一个bean 是否加载,使用什么注解?
在40岁老架构师尼恩的读者交流群中,近期多位读者成功获得了知名互联网企业的面试机会,如得物、阿里、滴滴等。然而,面对“Spring Boot自动装配机制”等核心面试题,部分读者因准备不足而未能顺利通过。为此,尼恩团队将系统化梳理和总结这一主题,帮助大家全面提升技术水平,让面试官“爱到不能自已”。
游客r43put2rqnbp4
5 0
得物面试:Springboot自动装配机制是什么?如何控制一个bean 是否加载,使用什么注解?
dlwlrma-晴子
|
6天前
|
XML Java 数据库
Spring boot的最全注解
Spring boot的最全注解
dlwlrma-晴子
16 4
明弟有理想
|
7天前
|
JSON NoSQL Java
springBoot:jwt&redis&文件操作&常见请求错误代码&参数注解 (九)
该文档涵盖JWT(JSON Web Token)的组成、依赖、工具类创建及拦截器配置,并介绍了Redis的依赖配置与文件操作相关功能,包括文件上传、下载、删除及批量删除的方法。同时,文档还列举了常见的HTTP请求错误代码及其含义,并详细解释了@RequestParam与@PathVariable等参数注解的区别与用法。
明弟有理想
13 2
明弟有理想
|
7天前
|
Java API Spring
springBoot:注解&封装类&异常类&登录实现类 (八)
本文介绍了Spring Boot项目中的一些关键代码片段,包括使用`@PathVariable`绑定路径参数、创建封装类Result和异常处理类GlobalException、定义常量接口Constants、自定义异常ServiceException以及实现用户登录功能。通过这些代码,展示了如何构建RESTful API,处理请求参数,统一返回结果格式,以及全局异常处理等核心功能。
明弟有理想
14 1
nanshaws
|
12天前
|
JSON 缓存 前端开发
SpringBoot的 ResponseEntity类讲解(具体讲解返回给前端的一些事情)
本文讲解了SpringBoot中的`ResponseEntity`类,展示了如何使用它来自定义HTTP响应,包括状态码、响应头和响应体,以及如何将图片从MinIO读取并返回给前端。
nanshaws
26 3
nanshaws
|
13天前
|
Java Spring 容器
Springboot3.2.1搞定了类Service和bean注解同名同类型问题修复
这篇文章讨论了在Spring Boot 3.2.1版本中,同名同类型的bean和@Service注解类之间冲突的问题得到了解决,之前版本中同名bean会相互覆盖,但不会在启动时报错,而在配置文件中设置`spring.main.allow-bean-definition-overriding=true`可以解决这个问题。
nanshaws
49 0
Springboot3.2.1搞定了类Service和bean注解同名同类型问题修复
Codelinghu
|
6天前
|
XML Java 数据格式
手动开发-简单的Spring基于注解配置的程序--源码解析
手动开发-简单的Spring基于注解配置的程序--源码解析
Codelinghu
19 0
木子0204
|
11天前
|
XML Java 数据格式
Java-spring注解的作用
Java-spring注解的作用
木子0204
14 0

热门文章

最新文章

  • 1
    SpringBoot开发案例之整合Dubbo提供者(一)
  • 2
    SpringBoot+Vue+kkFileView实现txt、doc、docx、md等文件在线预览)
  • 3
    java B2B2C Springboot电子商城系统-路由网关(zuul)
  • 4
    RocketMq集群安装&整合Springboot
  • 5
    springboot 集成kingbase的步骤
  • 6
    springboot线程池的使用和扩展
  • 7
    Springboot 整合tk-mybatis , 妈妈,我再也不想敲CRUD的代码了!
  • 8
    基于SpringBoot宠物领养系统的设计与实现(代码+数据库+文档)
  • 9
    SpringBoot从小白到精通(十)使用Interceptor拦截器,一学就会!
  • 10
    SpringBoot如何加载jar包外面的配置文件?
  • 1
    Spring Boot中的@Lazy注解:概念及实战应用
    136
  • 2
    docker部署postgresql数据库和整合springboot连接数据源
    143
  • 3
    spring kafka的问题集锦
    142
  • 4
    【spring】如何解决循环依赖
    202
  • 5
    【springboot】logback配置
    72
  • 6
    Python 爬虫:Spring Boot 反爬虫的成功案例
    638
  • 7
    JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
    543
  • 8
    Spring Boot版本管理
    46
  • 9
    Spring的@Retryable实现方法重试
    65
  • 10
    Spring Boot可以同时处理多少请求?
    111
  • 相关课程

    更多
  • 全面讲解Spring Cloud Alibaba技术栈(知识精讲+项目实战)第二阶段
  • 精通Spring Cloud Alibaba
  • 微服务框架 Spring Cloud 快速入门
  • Java Web开发系列课程 - Spring框架入门
  • Spring Boot 2.5.x开发实战
  • Spring Cloud微服务架构设计与开发实战
  • 相关电子书

    更多
  • 云栖社区特邀专家徐雷Java Spring Boot开发实战系列课程(第20讲):经典面试题与阿里等名企内部招聘求职面试技巧
  • 微服务架构模式与原理Spring Cloud开发实战
  • 阿里特邀专家徐雷Java Spring Boot开发实战系列课程(第18讲):制作Java Docker镜像与推送到DockerHub和阿里云Docker仓库
  • 相关实验场景

    更多
  • Spring-cloud-bus-rocketmq入门与实践
  • Spring-cloud-stream-binder-rocketmq入门与实践
  • 从零搭建Spring Boot的Hello World
  • 下一篇
    AI助理直击要害,从繁复中提炼精华——使用CDN加速访问OSS存储的图片

    玻璃钢生产厂家布拉格广场玻璃钢雕塑玻璃钢花盆哪个产品好用frp玻璃钢雕塑厂家上海玻璃钢牧童雨露雕塑宜春创意玻璃钢雕塑制作江门玻璃钢雕塑定做成品玻璃钢花盆报价河北多彩玻璃钢雕塑生产厂家黑龙江公园玻璃钢雕塑图片户外景观玻璃钢雕塑多少钱蚌埠欧式玻璃钢雕塑设计江西玻璃钢花盆造型张掖人物玻璃钢雕塑成都秋季商场美陈嘉定区镜面玻璃钢雕塑推荐厂家西安彩绘玻璃钢雕塑无锡玻璃钢园林雕塑厂家直销香港圣诞节 商场美陈湖南佛像玻璃钢雕塑订做价格太湖石玻璃钢卡通雕塑价格西安玻璃钢雕塑制造厂芒市玻璃钢雕塑订做购物广场商场中秋美陈开封玻璃钢浮雕广场雕塑湖南玻璃钢小羊动物雕塑应城玻璃钢雕塑厂家抚州公园玻璃钢雕塑订做价格湖北创意玻璃钢雕塑长春玻璃钢雕塑公司玻璃钢雕塑6米报价香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

    玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化