Spring Boot 源码学习之@SpringBootApplication注解

news2024/11/25 4:25:19

@SpringBootApplication 注解

  • 引言
  • 主要内容
    • 1. 创建 Spring Boot 项目
    • 2. Spring Boot 入口类
    • 3. @SpringBootApplication 介绍
  • 总结

引言

在 Huazie 前面的博文 《Spring Boot 核心运行原理介绍》中,我们初步了解了 Spring Boot 核心运行原理,知道了 @EnableAutoConfiguration 是用来开启自动配置的注解。但创建过 Spring Boot 项目的读者肯定会说,我们并没有直接看到这个注解,实际上前面我也提到,它是由组合注解 @SpringBootApplication 引入的。

至于 @EnableAutoConfiguration 的讲解,我将放到后面再深入源码了解,本篇先介绍 组合注解 @SpringBootApplication

好了,废话不多说,看下面介绍:

主要内容

1. 创建 Spring Boot 项目

首先,我们打开 Intellij IDEA 开发工具,选择 File -> New -> Project

在这里插入图片描述
然后打开 New Project ,选择 Spring Initializr【这是用来创建 Spring Boot 项目】:

在这里插入图片描述

选择 Next,打开 Project Metadata【这里可以配置项目的一些基础信息】:

在这里插入图片描述

继续 Next,打开 Dependencies【有需要其他依赖可以添加】:

在这里插入图片描述

继续 Next,选择你的 Spring Boot 项目位置:

在这里插入图片描述

最后点 Finish 完成。

注意: 刚才新建的项目中,如果因为 Spring Boot 的版本问题导致项目报错,那就换个版本再试试。

2. Spring Boot 入口类

上述新建好的项目创建完成默认会生成一个 XXXApplication 的入口类。默认情况下,这个类的命名规则都是 artifactId + ApplicationartifactId 首字母大写】:

在这里插入图片描述
在这里插入图片描述
如上图中的 DemoApplication 就是我们这里 Spring Boot 项目的入口类,代码如下所示:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

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

}

在上述的 Spring Boot 入口类 DemoApplication 中,唯一的注解就是 @SpringBootApplication。前面我们也提到了,它是通过其内部组合的 @EnableAutoConfiguration 来开启自动配置功能。

下面我们来详细介绍下 @SpringBootApplication 注解:

3. @SpringBootApplication 介绍

先来看 @SpringBootApplication 的源码【版本:2.7.9】:


@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 {

	/**
	 * 排除特定的自动配置类,使它们永远不会被应用
	 * @return 要排除(禁用)的类
	 */
	@AliasFor(annotation = EnableAutoConfiguration.class)
	Class<?>[] exclude() default {};

	/**
	 * 排除特定的自动配置类名称,以确保它们永远不会被应用
	 * @return 要排除的自动配置类名称
	 * @since 1.3.0
	 */
	@AliasFor(annotation = EnableAutoConfiguration.class)
	String[] excludeName() default {};

	/**
	 * 用于扫描带注解组件的基础包。使用 {@link #scanBasePackageClasses} 可以使用类型安全的方式替代基于字符串的包名。
	 * <p>
	 * 注意:该设置仅对 {@code @ComponentScan} 注解有效,不影响 {@code @Entity} 扫描或 Spring Data 的 {@link Repository} 扫描。
	 * 对于这些情况,你应该添加 {@link org.springframework.boot.autoconfigure.domain.EntityScan @EntityScan} 和
	 * {@code @Enable...Repositories} 注解。
	 * @return 要进行扫描的基础包
	 * @since 1.3.0
	 */
	@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
	String[] scanBasePackages() default {};

	/**
	 * 用于指定要扫描带注解组件的包的类型安全方式。将扫描指定类所在的包。
	 * <p>
	 * 考虑在每个包中创建一个特殊的空类或接口,只用于作为此属性引用的标记类。
	 * <p>
	 * 注意:该设置仅对 {@code @ComponentScan} 注解有效,不影响 {@code @Entity} 扫描或 Spring Data 的 {@link Repository} 扫描。
	 * 对于这些情况,你应该添加 {@link org.springframework.boot.autoconfigure.domain.EntityScan @EntityScan} 和
	 * {@code @Enable...Repositories} 注解。
	 * @return 要进行扫描的基础包
	 * @since 1.3.0
	 */
	@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
	Class<?>[] scanBasePackageClasses() default {};

	/**
	 * 用于在 Spring 容器中为检测到的组件命名的 {@link BeanNameGenerator} 类。
	 * <p>
	 * {@link BeanNameGenerator} 接口本身的默认值表示应该使用处理此 {@code @SpringBootApplication} 注解的扫描器的继承的 bean 名称生成器,
	 * 例如默认的 {@link AnnotationBeanNameGenerator} 或在引导时提供给应用程序上下文的任何自定义实例。
	 * @return 要使用的 {@link BeanNameGenerator}
	 * @see SpringApplication#setBeanNameGenerator(BeanNameGenerator)
	 * @since 2.3.0
	 */
	@AliasFor(annotation = ComponentScan.class, attribute = "nameGenerator")
	Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;

	/**
	 * 指定是否应代理 {@link Bean @Bean} 方法以强制执行 bean 的生命周期行为,例如,即使在用户代码中直接调用 {@code @Bean} 方法,
	 * 也能返回共享的单例 bean 实例。此功能需要方法拦截,通过运行时生成的 CGLIB 子类来实现,其中包括一些限制,例如配置类及其方法不允许声明为 {@code final}。
	 * <p>
	 * 默认值为 {@code true},允许在配置类内部进行 'inter-bean references',同时允许从另一个配置类中调用此配置的 {@code @Bean} 方法。
	 * 如果每个特定配置的 {@code @Bean} 方法都是自包含的并且设计为容器使用的普通工厂方法,则可以将此标志切换为 {@code false},
	 * 以避免 CGLIB 子类处理。
	 * <p>
	 * 关闭 bean 方法拦截将实际上像在非 {@code @Configuration} 类上声明的那样单独处理 {@code @Bean} 方法,也就是 "@Bean Lite Mode"
	 * (参见 {@link Bean @Bean 的文档})。因此,在行为上等同于删除 {@code @Configuration} 注解。
	 * @since 2.2
	 * @return 是否代理 {@code @Bean} 方法
	 */
	@AliasFor(annotation = Configuration.class)
	boolean proxyBeanMethods() default true;

}

通过查看上述源码,我们可以看到 @SpringBootApplication 注解提供如下的成员属性【这里默认大家都是知道 注解中的成员变量是以方法的形式存在的】:

  • exclude :根据类(Class)排除指定的自动配置,该成员属性覆盖了 @SpringBootApplication 中组合的 @EnableAutoConfiguration 中定义的 exclude 成员属性。
  • excludeName :根据类名排除指定的自动配置,覆盖了 @EnableAutoConfiguration 中定义的 excludeName 成员属性。
  • scanBasePackages :指定扫描的基础 package,用于扫描带注解组件的基础包,例如包含 @Component 等注解的组件。
  • scanBasePackageClasses :指定扫描的类,用于相关组件的初始化。
  • nameGenerator :用于在 Spring 容器中为检测到的组件命名的 BeanNameGenerator 类。
  • proxyBeanMethods :指定是否代码 @Bean 方法以强制执行 bean 的生命周期行为。该功能需要通过运行时生成 CGLIB 子类来实现方法拦截。不过它包括一定的限制,例如配置类及其方法不允许声明为 final 等。proxyBeanMethods 的默认值为 true,允许配置类中进行 inter-bean references(bean 之间的引用)以及对该配置的 @Bean 方法的外部调用。如果 @Bean 方法都是自包含的,并且仅提供了容器使用的普通工程方法的功能,则可设置为 false,避免处理 CGLIB 子类。另外我们从源码中 @since 2.2 处也可以看出来,该属性是在 Spring Boot 2.2 版本新增的。

细心的读者,可能看过上面的源码会发现,@SpringBootApplication 注解的成员属性上大量使用了 @AliasFor 注解,那该注解有什么作用呢?

@AliasFor 注解用于桥接其他注解,它的 annotation 属性中指定了所桥接的注解类。如果我们点到 annotation 属性配置的注解中,可以看出 @SpringBootApplication 注解的成员属性其实已经在其他注解中定义过了。那之所以使用 @AliasFor 注解并重新在 @SpringBootApplication 中定义,主要就是为了减少用户在使用多注解上的麻烦。

知识拓展:
简单总结一下 @AliasFor 的作用:

  • 定义别名关系:通过在注解属性上使用 @AliasFor 注解,可以将一个属性与另一个属性建立别名关系。这意味着当使用注解时,你可以使用别名属性来设置目标属性的值。
  • 属性互通:通过在两个属性上使用 @AliasFor 注解,并且将它们的 attribute 属性分别设置为对方,可以实现属性之间的双向关联。这意味着当设置其中一个属性的值时,另一个属性也会自动被赋予相同的值。
  • 注解继承:当一个注解 A 使用 @AliasFor 注解指定了另一个注解 B 的属性为自己的别名属性时,如果类使用了注解 A,那么注解 B 的相关属性也会得到相应的设置。

Spring Boot 早期的版本中并没有 @SpringBootConfiguration 注解,它是后面的版本新加的,其内组合了 @Configuration 注解,如下图所示:

在这里插入图片描述

@EnableAutoConfiguration 注解组合了 @AutoConfigurationPackage 注解,如下图所示:

在这里插入图片描述

除了一些元注解和基础注解,我们用一张类图来描述下 @SpringBootApplication 注解的组合结构:

在这里插入图片描述

从上图中,我们可以总结一下 @SpringBootApplication 注解的核心作用,如下:

  • 组合 @EnableAutoConfiguration,用于开启 Spring Boot 的自动配置功能;
  • 组合 @ComponentScan,用于激活 @Component 等注解类的初始化;
  • 组合 @SpringBootConfiguration,用于标识一个类为配置类,以便在 Spring 应用程序上下文中进行配置。

总结

本篇通过查看 @SpringBootApplication 注解的源码,介绍其成员属性和组合注解的相关内容,这些内容将为我们后续的源码学习打下基础。下一篇博文,我们将开始介绍 @EnableAutoConfiguration 注解,开启 Spring Boot 的自动配置功能,敬请期待!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/760673.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

#挑战Open AI!马斯克宣布成立xAI,你怎么看?# 马斯克的xAI:充满困难与希望

文章目录 1.什么是xAI公司&#xff1f;2.xAI公司的图标3.“反AI斗士”马斯克进军AI&#xff1a;期待与挑战并存3.1 关于马斯克……3.2 这位“反AI斗士”……3.3 我的看法3.4 可能会遇到的困难与优势3.5 蓄谋已久的马斯克……3.6 xAI“全明星阵容”3.7 总结 4.百模大战&#xff…

git第一次拉取远程分支项目(ssh的方式)

一.生成SSH keys,并将生成的key复制到远程库 1.本地用命令生成密钥对。 ssh-keygen -t rsa -C "yourEmailAddress" 或 ssh-keygen -t ed25519 -C "yourEmailAddress" 按三次enter直接生成密钥对。 2.切换至ssh目录下&#xff0c;复制key&#xff08;公…

软件测试值不值得学,2023软件测试行情分析

目录 1、人们的生活离不开软件&#xff0c;有软件的地方就有测试 2、测试工程师特别是自动化测试工程师的需求会越来越大 3、软件测试经验越丰富越受欢迎&#xff0c;不存在35岁限制。 4、所有新兴行业比如chat-gtp&#xff0c;车载系统等都需要测试工程师 薪资 就业 软…

设计模式——桥梁模式

桥梁模式 定义 桥梁模式&#xff08;Bridge Pattern&#xff09;也叫做桥接模式。 将抽象和显示解耦&#xff0c;使得两者可以独立地变化。 优缺点、应用场景 优点 抽象和实现的解耦。 这是桥梁模式的主要特点&#xff0c;它完全是为了解决继承的缺点而提出的设计模式。优…

从C到C++ | C++入门(二)

目录 缺省参数 1.)全缺省 2.)半缺省 函数重载 1.) 参数类型不同 2.) 参数个数不同 3.) 参数顺序不同 函数重载的原理&#xff1a; &#xff01;&#xff01;&#xff01;注意 &#xff01;&#xff01;&#xff01; 引用 1.) 引用做参数 2.) 引用做返回值 引用和…

C#使用DataGridView模拟绘图

接到一个需求&#xff0c;绘制一个水管线的图片&#xff0c;这种管线可以有12种分段方法&#xff0c;最后将这12种分段方法合并后在一条水管线上展示&#xff0c;要求&#xff1a; ⒈支持分段的属性展示&#xff1b; ⒉要求每个分段都能清晰展示&#xff0c;分段数在0&#xff…

一天吃透JVM面试八股文

内容摘自我的学习网站&#xff1a;topjavaer.cn 什么是JVM&#xff1f; JVM&#xff0c;全称Java Virtual Machine&#xff08;Java虚拟机&#xff09;&#xff0c;是通过在实际的计算机上仿真模拟各种计算机功能来实现的。由一套字节码指令集、一组寄存器、一个栈、一个垃圾回…

C++11(1)——新增用法零碎总结

目录 1. C11简介 2. 统一的列表初始化 2.1 &#xff5b;&#xff5d;初始化 2.2 std::initializer_list std::initializer_list是什么类型&#xff1a; std::initializer_list使用场景&#xff1a; 让模拟实现的vector也支持{}初始化和赋值 1. C11简介 在2003年C标准委员会…

【雕爷学编程】Arduino动手做(163)---大尺寸8x8LED方格屏模块2

37款传感器与模块的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&#x…

学无止境·MySQL⑧(Redis)

Redis和Mongodb练习 Redis1、安装redis2、string类型数据的命令操作&#xff1a;设置键值&#xff1a;读取键值数值类型自增1数值类型自减1查看值的长度 3、list类型数据的命令操作对列表city插入元素&#xff1a;Shanghai Suzhou Hangzhou将列表city里的头部的元素移除将name列…

AI炒股:用Claude来分析A股2023年中报业绩预告

Claude是和ChatGPT类似的AI大模型&#xff0c;据测试 AI 的水平能力接近 GPT-4&#xff0c;支持高达 100K token 的上下文。Claude只需要到官方网站注册账号后就可以直接免费使用。不过&#xff0c;目前智能美国和英国的 IP 可以注册和使用。 Claude支持上传文档功能&#xff…

计算机网络基础第三章

一、数据链路层功能概述 1.1 数据链路层基本概念 结点&#xff1a;主机、路由器 链路&#xff1a;网络中两个结点之间的物理通道&#xff0c;链路的传输介质主要有双绞线、光纤和微波。分为有线链路、无线链路 数据链路&#xff1a;网络中两个结点之间的逻辑通道&#xff0c;…

C++ 异常

文章目录 一. C语言的错误处理二. C的异常三. 异常的抛出与捕获1. 异常的抛出与匹配机制2. 在函数调用链中异常栈展开匹配原则3. 异常安全 四. 多态在异常中的应用五. C标准库的异常体系六. 异常规范七. 异常的优缺点结束语 一. C语言的错误处理 在C语言中&#xff0c;我们常见…

IDEA快捷键及模版配置

一、快捷键 1、常用的快捷键 删除当前行, 默认是 ctrl Y 自己配置 ctrl d (搜delete)复制当前行, 自己配置 ctrl alt 向下光标 (搜duplicate)补全代码 alt /添加注释和取消注释 ctrl / 【第一次是添加注释&#xff0c;第二次是取消注释】导入该行需要的类 先配置 auto …

S3C2440点亮LED(裸机开发)

文章目录 前言一、环境介绍一、GPIO介绍二、点亮开发板的LED1.预备动作2.led代码 总结 前言 本期和大家主要分享的是使用S3C2440开发板点亮一个LED灯&#xff0c;可能大家拿到开发板之后做的第一件事情都是点灯&#xff0c;这是为什么呢&#xff1f;因为点灯这件事情不仅能够检…

TCP三次握手调优

SYN: Synchronize Sequence Numbers。同步序列号 服务端的优化 当服务器收到 SYN 报文后&#xff0c;服务器会立刻回复 SYNACK 报文&#xff0c;既确认了客户端的序列号&#xff0c;也把自己的序列号发给了对方。此时&#xff0c;服务器端出现了新连接&#xff0c;状态是 SYN…

MySQL系列之行转列,列转行

MySQL系列之行转列&#xff0c;列转行 之前业务出现了需要行转列的场景&#xff0c;记录一下 SQL中AVG、COUNT、SUM、MAX等聚合函数对NULL值的处理 Mysql Max、 Where和 Group By 三个关键字同时使用 执行顺序 MySql 行转列的玩法 &#xff0c;实战案例教学&#xff08;MAX…

Eolink Apikit,0 代码可拖拽的自动化测试神器

目录 一、从测试到可拖拽的自动化测试二、0 代码&#xff0c;图形化&#xff0c;好用到飞起通过图形化操作、拖拽的方式搭建测试流程 三、Eolink Apikit&#xff0c;一站式 API 研发协作平台1、多协议支持2、多种数据重用3、报告、分析、告警4、支持持续集成和部署 四、Apikit …

QT基础入门之文件操作

一、概述 Qt 作为一个通用开发库&#xff0c;提供了跨平台的文件操作能力。Qt 通过QIODevice提供了对 I/O 设备的抽象&#xff0c;这些设备具有读写字节块的能力。下面是 I/O 设备的类图&#xff1a; QIODevice&#xff1a;所有I/O设备类的父类&#xff0c;提供字节块读写的通…

Sentinel流量规则模块(降级)

sentinel的常见页面的简介 流控是对外部来的大流量进行控制&#xff0c;熔断降级的视角是对内部问题进行处理。 Sentinel降级会在调用链路中某个资源出现不稳定状态时&#xff08;例如调用超时或异常比例升高&#xff09;&#xff0c;对这个资源的调用进行限制&#xff0c;…