@SpringBootApplication和SpringApplication.run源码解析:

news2024/11/23 13:20:57

文章目录

  • 一、@SpringBootApplication和自动配置
    • 1、主要功能
    • 2、@SpringBootConfiguration
    • 3、@EnableAutoConfiguration
    • 4、@ComponentScan
    • 5、Spring boot自动配置
        • 5.1、@Configuration开启自动配置
        • 5.2、查看自动配置
        • 5.3、禁用自动配置
  • 二、run()
      • new SpringApplication()


当前版本

        <spring-boot.version>2.3.12.RELEASE</spring-boot.version>

一、@SpringBootApplication和自动配置

/**
 * Indicates a {@link Configuration configuration} class that declares one or more
 * {@link Bean @Bean} methods and also triggers {@link EnableAutoConfiguration
 * auto-configuration} and {@link ComponentScan component scanning}. This is a convenience
 * annotation that is equivalent to declaring {@code @Configuration},
 * {@code @EnableAutoConfiguration} and {@code @ComponentScan}.
 *
 * @author Phillip Webb
 * @author Stephane Nicoll
 * @author Andy Wilkinson
 * @since 1.2.0
 */
@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 {

1、主要功能

  • @EnableAutoConfiguration:启用Spring Boot的自动配置机制。
  • == @ComponentScan==:对应用程序所在的包启用 @Component 扫描(见最佳实践)。
  • @SpringBootConfiguration:允许在Context中注册额外的Bean或导入额外的配置类。这是Spring标准的 @Configuration 的替代方案,有助于在你的集成测试中检测配置。

这几个功能都可以一定程度的自定义 ,列如你不需要在你的应用程序中使用组件扫描或配置属性扫描。

@SpringBootConfiguration(proxyBeanMethods = false)就 不能自动检测到 @Component 和 @ConfigurationProperties(这两个是SpringBootConfiguration类下引用了这两个注解) 注解的类,而是明确导入用户定义的Bean

@SpringBootConfiguration(proxyBeanMethods = false)
@EnableAutoConfiguration
@Import({ SomeConfiguration.class, AnotherConfiguration.class })
public class MyApplication {

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

}

2、@SpringBootConfiguration

//指示类提供Spring Boot application@Configuration。
//可以用作Spring的标准@Configuration注释的替代品,以便可以自动找到配置(例如在测试中)。
//应用程序应该只包含一个@SpringBootConfiguration,大多数惯用的SpringBoot应用程序将从@SpringBootApplication继承它。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
@Indexed
public @interface SpringBootConfiguration {

3、@EnableAutoConfiguration

启用Spring应用程序上下文的自动配置,尝试猜测和配置您可能需要的bean。自动配置类通常基于类路径和您定义的bean来应用。例如,如果您的类路径上有tomcat-embedded.jar,那么您可能想要一个TomcatServlet WebServerFactory(除非您定义了自己的Servlet WebServerFactoryBean)。
当使用@SpringBootApplication时,上下文的自动配置会自动启用,因此添加此注释没有其他效果。
自动配置试图尽可能地智能化,并将随着您定义更多自己的配置而退出。您总是可以手动排除()任何您永远不想应用的配置(如果您没有访问权限,请使用excludeName())。您也可以通过spring.autoconfig.exclude属性排除它们。自动配置总是在用户定义的bean注册后应用

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

4、@ComponentScan

配置与@Configuration类一起使用的组件扫描指令。提供与Spring XML的<context:component scan>元素并行的支持。
可以指定basePackageClasses或basePackages(或其别名值)来定义要扫描的特定包。
如果未定义特定的包,则将从声明此注释的类的包进行扫描。
请注意,context:component-scan元素具有annotation-config属性;然而,这个注释没有。这是因为在几乎所有情况下,当使用@ComponentScan时,都会假设默认的注释配置处理(例如处理@Autowired和friends)。
此外,当使用AnnotationConfigApplicationContext时,注释配置处理器始终是注册的,这意味着在@ComponentScan级别禁用它们的任何尝试都将被忽略。

 
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {

5、Spring boot自动配置

5.1、@Configuration开启自动配置

SpringBoot的自动装配机制会试图根据你所添加的依赖来自动配置你的Spring应用程序。比如你添加了数据库相关的依赖,Springboot就会自动配置数据库相关的内容,(你引入mysql依赖,但是你不去配置,就会触发数据库资源配置问题)

上面的@SpringBootApplication 或 @EnableAutoConfiguration 注解就是开启自动配置的注解,这两个在系统中只能出现一次
其他的自动配置使用 @Configuration注解注入自动配置

5.2、查看自动配置

如果要 的可以进入Debug模式查看
进入方法有

  • 命令行 启动时加入 --debug (jar 直接加就可以 ),maven命令行 mvn spring-boot:run --debug
  • properties添加属性 debug=true
  • 通过idea启动项上添加VM 配置 –Ddebug 新版idea只需要在 启动配置页面ALT+D就可触发在这里插入图片描述
5.3、禁用自动配置

第一个方式

@SpringBootApplication(exclude = { XXXXX.class })  

第二个方式

properties配置

spring.autoconfigure.exclude=XXXXXX

这两个配置其实是一个配置,只是写的地方不一样
在@SpringBootApplication的exclude属性

/**
	 * Exclude specific auto-configuration classes such that they will never be applied.
	 *  排除特定的自动配置类别,使其永不被应用。
	 * @return the classes to exclude
	 */
	@AliasFor(annotation = EnableAutoConfiguration.class)
	Class<?>[] exclude() default {};

	/**
	 * Exclude specific auto-configuration class names such that they will never be
	 * applied.
	 * @return the class names to exclude
	 * @since 1.3.0
	 */
	@AliasFor(annotation = EnableAutoConfiguration.class)
	String[] excludeName() default {};

可以注意, SpringBootApplication里面有一个exclude和 excludeName
因为有的像禁用的包没有导入的包会找不到.class文件 这个上海就可以使用包的全路径名类似org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,这个样子

自动配置是非侵入性的。Spring有一套默认的配置,当你开始自定义配置时,你配置的bean会自动使用代替默认配置

TIPS Spring文档 中提到一个点,不要去使用自动配置类中的方法或者属性,包括嵌套的配置类。都不建议你去使用。

无论是单一原则,还是系统后期版本变动都不应该去使用这些。

二、run()

直接的说法就是 run方法是 SpringApplication类下的一个方法,是负责启动Spring Boot的入口

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

SpringApplication下供有三个run方法分别是

  • 静态方法, 使用默认设置从指定源运行SpringApplication。
package org.springframework.boot;

	public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
		return run(new Class<?>[] { primarySource }, args);
	}
  • 静态方法, 使用默认设置和用户提供的参数从指定的源运行SpringApplication。
package org.springframework.boot;

	public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
		return new SpringApplication(primarySources).run(args);
	}
  • 运行Spring应用程序,创建并刷新一个新的ApplicationContext。
package org.springframework.boot;

  public ConfigurableApplicationContext run(String... args) {
 暂时省略。。。。。
    }
  • 当你需要灵活配置或者又其他和Spring应用结构不同的情况下使用最后一个,

  • 前两个其实是一个,第一个方法也会走到第二个run方法,是等价的,他这样就是为了同时满足多模块程序和单模块程序,

  • 你可以发现,默认情况下他是从第一个方法进入,将参数格式重组放到第二个方法,第二个方法在创建一个新对象去调用第三个run方法

问题 那他为什么要这样做,实现你需要了解SpringApplication是的创建方法

new SpringApplication()

package org.springframework.boot;

public SpringApplication(Class<?>... primarySources) {
		this(null, primarySources);
	} 

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
		//设置资源加载器
		this.resourceLoader = resourceLoader;
		//主应用程序类判空
		Assert.notNull(primarySources, "PrimarySources must not be null");
		//赋值主应用程序集合
		this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
		//判断启动类型 
		this.webApplicationType = WebApplicationType.deduceFromClasspath(); 
		
		setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
		this.mainApplicationClass = deduceMainApplicationClass();
	}

你可以看到默认情况下,是通过第一个在调用第二个,第一个参数ResourceLoader 传了一个空的资源进去,第二个是要 加载的应用程序

  • 前三行代码先对基础的 resourceLoader ,primarySources 进行赋值(LinkedHashSet1
  • 第四行在 通过 webApplicationType2 的deduceFromClasspath方法,根据你的文件路径格式判断启动什么样的应用程序
  • 第五行:初始化配置路径,默认为“META-INF/spring.factories
  • 第六行:初始化
  • 下班了明天再写

参考文章

https://blog.csdn.net/u014131617/article/details/85335692

Spring中文文档

Spring文档


  1. Set接口的哈希表和链表实现, 具有可预测的迭代顺序。https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashSet.html ↩︎

  2. 请查看类 org.springframework.boot.WebApplicationType; ↩︎

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

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

相关文章

Redis常用命令!!!

一、String&#xff08;字符串&#xff09; 1、set 设置单个key的value set key value set name 小明 2、mset 设置多个key的value mset key1 value1 key2 value2mset name1 小美 name2 小帅 3、get 获取单个key的值 get key get name4、mget 获取多个key的值 mget key1 key2 k…

[XOA Code]Test-suite-RFC2544

Testsuite-RFC2544&#xff0c;微信公众号也在间断的更新中&#xff0c;博客码码字&#xff0c;节奏老是踩不对&#xff0c;没什么条理 难道要不破不立&#xff0c;要全部推倒了重新来吗&#xff0c;....5555 XOA-2544测试 Dataset.py from typing import Any, List, Tuple,…

3.Spring Bean

3.1 Bean的配置 Spring可以看作一个大型工厂&#xff0c;生产和管理Spring容器中的bean。如何使用这个工厂生产和管理bean&#xff0c;需要开发者将bean配置在Spring的配置文件中。Spring框架支持XML和Properties两种格式的配置文件&#xff0c;在实际开发中&#xff0c;常用X…

天府锋巢直播产业基地科学城核心区域

天府锋巢直播产业基地位于天府新区科学城板块&#xff0c;地理位置优越&#xff0c;交通便利&#xff0c;是集直播电商、创新创业、人才培养等多功能于一体的现代化成都直播基地。这里汇聚了众多优秀的直播电商企业和创业团队&#xff0c;为直播电商行业的发展注入了强大的动力…

算法打卡day27|贪心算法篇01|Leetcode 455.分发饼干、376. 摆动序列、53. 最大子序和

贪心算法理论基础 定义 贪心的本质是选择每一阶段的局部最优&#xff0c;从而达到全局最优。 例如&#xff0c;有一堆不同数值的钞票&#xff0c;可以拿走十张&#xff0c;如果想达到最大的金额可以指定每次拿最大的&#xff0c;最终结果就是拿走最大数额的钱。 每次拿最大的就…

混合像元分解:Matlab如何帮助揭示地表组成?

光谱和图像是人们观察世界的两种方式&#xff0c;高光谱遥感通过“图谱合一”的技术创新将两者结合起来&#xff0c;大大提高了人们对客观世界的认知能力&#xff0c;本来在宽波段遥感中不可探测的物质&#xff0c;在高光谱遥感中能被探测。以高光谱遥感为核心&#xff0c;构建…

分享一道DFS常见题目 C++实现路径之谜

题目描述&#xff1a;路径之谜 小明冒充X星球的骑士&#xff0c;进入了一个奇怪的城堡。 城堡里边什么都没有&#xff0c;只有方形石头铺成的地面。 假设城堡地面是 n x n 个方格。【如图1.png】所示。 按习俗&#xff0c;骑士要从西北角走到东南角。 可以横向或纵向移动&…

3个新变化!2024年国家高新技术企业认定攻略

根据《党和国家机构改革方案》和《党中央、国务院议事协调机构优化调整方案》&#xff0c;经报党中央、国务院批准&#xff0c;现将工业和信息化部职责、机构、编制调整&#xff0c;2024年由工信部管理国家高新技术企业认定工作。 总的来说&#xff0c;通过对政策的研究和解读…

Leetcode 76 最小覆盖子串 java版

官网链接&#xff1a; . - 力扣&#xff08;LeetCode&#xff09; 1. 问题&#xff1a; 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串&#xff0c;则返回空字符串 "" 。 注意&#xff1a; 对于 …

langchian入门四:LLM+Agents代理=贾维斯?让大模型拥有三头六臂

什么是Agent 在日常生活中,不难发现,chatgpt通过文本输入进行处理后返回的也是文本内容,就像是一个只有头的人,能听能思考能说话,但是无法行动.而Agent是一种能够自主决策、采取行动以达到某种目标的实体。被解释为"智能体"或者"代理". 代理的核心思想是…

Java全栈课程之Linux———基本属性

一、看懂文件属性 Linux系统是一种典型的多用户系统&#xff0c;不同的用户处于不同的地位&#xff0c;拥有不同的权限。为了保护系统的安全性&#xff0c;Linux系统对不同的用户访问同一文件&#xff08;包括目录文件&#xff09;的权限做了不同的规定。 在Linux中我们可以使…

Mysql数据库——数据备份与恢复

目录 一、数据备份的重要性 二、数据库备份的分类 1.从物理与逻辑的角度分类 2.从数据库的备份策略角度&#xff0c;备份可分为 2.1完全备份 2.2差异备份 2.3增量备份 2.4总结 三、常见的备份方法 四、Mysql数据库完全备份 1.完全备份定义 2.优缺点 3.数据库完全备…

代码随想录算法训练营第25天|LeetCode106.中序和后序遍历构造二叉树、LeetCode105.中序和先序遍历构造二叉树

代码随想录算法训练营第25天|LeetCode106.中序和后序遍历构造二叉树、LeetCode105.中序和先序遍历构造二叉树 1、LeetCode106.中序和后序遍历构造二叉树 106. 从中序与后序遍历序列构造二叉树 - 力扣&#xff08;LeetCode&#xff09; 知道理论怎么求&#xff0c;但是太久没写…

Adaptive Partitioning

qnx开源代码 GitHub - vocho/openqnx: mirror of git://git.code.sf.net/p/monartis/openqnx http://www.qnx.com/developers/docs/7.0.0/#com.qnx.doc.adaptivepartitioning.userguide/topic/about_howtouseguide_.html ap是对进程和线程集合分配最小的系统资源&#xff0c;目…

基于nodejs+vue宿舍管理系统python-flask-django-php

随着信息时代的来临&#xff0c;过去的传统管理方式缺点逐渐暴露&#xff0c;对过去的传统管理方式的缺点进行分析&#xff0c;采取计算机方式构建宿舍管理系统。本文通过课题背景、课题目的及意义相关技术&#xff0c;提出了一种楼宇信息、宿舍信息、宿舍安排、缺勤信息等于一…

OceanBase中NOT EXISTS是否需要被改写

作者简介 张瑞远&#xff0c;曾经从事银行、证券数仓设计、开发、优化类工作&#xff0c;现主要从事电信级IT系统及数据库的规划设计、架构设计、运维实施、运维服务、故障处理、性能优化等工作。 持有Orale OCM,MySQL OCP及国产代表数据库认证。 获得的专业技能与认证包括 Oce…

直播预告丨困气排气解决新方案--毅速金属3D打印随形透气钢

您是否也遇到过这些问题 模具困气造成产品出现注塑瑕疵&#xff0c;但复杂的产品形状导致无法开排气槽 常规透气钢需要拆镶件导致工件强度下降 某些工件部分不接受分模线区域无法拆镶件无法使用常规透气钢 面对越来越复杂的产品和结构&#xff0c;越来越多需要透气、保压、…

全网最新网络安全自学路线,最详细没有之一!!!

在各大平台搜的网安学习路线都太粗略了。。。。看不下去了&#xff01; 我把自己整理的系统学习路线&#xff0c;拿出来跟大家分享了&#xff01; 建议的学习顺序&#xff1a; 一、网络安全学习普法&#xff08;心里有个数&#xff0c;要进去坐几年&#xff01;&#xff09; 1…

Spring 面试——restcontroller/requestmapping

RestController Controller ResponseBody Controller&#xff1a;包含Component&#xff0c;把当前类声明成为一个 bean ResponseBody&#xff1a;表示方法返回的结果直接作为 HTTP 响应的内容&#xff0c;不是返回视图 3.RequestMapping注解的基本用法_哔哩哔哩_bilibili

Linux文件系列:磁盘,文件系统,软硬链接

Linux文件系列:磁盘,文件系统,软硬链接 一.磁盘相关知识1.磁盘机械构成2.磁盘物理存储3.磁盘逻辑存储1.LBA地址2.磁盘的分区和分组 二.文件系统和inode1.inode结构体2.文件系统1.Super Block(超级块)2.Group Descriptor Table(块组描述表GDT)3.inode Table4.Data Blocks5.Block…