当前位置: 首页 > news >正文

拆解Spring boot:Springboot为什么如此丝滑而简单?源码剖析解读自动装配

963034f17590412b808770f619144970.png

🎉🎉欢迎光临,终于等到你啦🎉🎉

🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀

🌟持续更新的专栏《Spring 狂野之旅:从入门到入魔》 🚀

本专栏带你从Spring入门到入魔 

这是苏泽的个人主页可以看到我其他的内容哦👇👇

努力的苏泽http://suzee.blog.csdn.net/

 


 

springboot帮我们做了什么

一个字--自动!

通常搭建一个基于spring的web应用,我们需要做以下工作:

1、pom文件中引入相关jar包,包括spring、springmvc、redis、mybaits、log4j、mysql-connector-java 等等相关jar ...

2、配置web.xml,Listener配置、Filter配置、Servlet配置、log4j配置、error配置 ...

3、配置数据库连接、配置spring事务

4、配置视图解析器

5、开启注解、自动扫描功能

6、配置完成后部署tomcat、启动调试

......

这些都是Spring boot在背后默默为我们做的工作

那 有没有想过为什么? 

本文给大家来解读Spring的源码 拆解他的自动配置 一步一步解释为什么Springboot为何那么强大

 

 

进入他的细节源码之前 首先关注 ---架构

cb4b233de36d4b1c8bab048bf0e7cf94.png

解读SpringBootApplication

@Target(ElementType.TYPE)            // 注解的适用范围,其中TYPE用于描述类、接口(包括包注解类型)或enum声明
@Retention(RetentionPolicy.RUNTIME)  // 注解的生命周期,保留到class文件中(三个生命周期)
@Documented                          // 表明这个注解应该被javadoc记录
@Inherited                           // 子类可以继承该注解
@SpringBootConfiguration             // 继承了Configuration,表示当前是注解类
@EnableAutoConfiguration             // 开启springboot的注解功能,springboot的四大神器之一,其借助@import的帮助
@ComponentScan(excludeFilters = {    // 扫描路径设置(具体使用待确认)@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
...
}

@Configuration

这里的@Configuration 对我们来说不陌生,它就是 JavaConfig 形式的 Spring Ioc 容器的配置类使用的那个@Configuration,SpringBoot 社区推荐使用基于 JavaConfig 的配置形式,所以,这里的启动类标注了@Configuration 之后,本身其实也是一个 IoC 容器的配置类。 举几个简单例子回顾下,XML 跟 config 配置方式的区别:

表达形式层面 基于 XML 配置的方式是这样:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"default-lazy-init="true"><!--bean定义-->
</beans>

而基于 JavaConfig 的配置方式是这样:

@Configuration
public class MockConfiguration{//bean定义
}

任何一个标注了@Configuration 的 Java 类定义都是一个 JavaConfig 配置类。

注册 bean 定义层面 基于 XML 的配置形式是这样:

<bean id="mockService" class="..MockServiceImpl">...
</bean>

而基于 JavaConfig 的配置形式是这样的:

@Configuration
public class MockConfiguration{@Beanpublic MockService mockService(){return new MockServiceImpl();}
}

任何一个标注了@Bean 的方法,其返回值将作为一个 bean 定义注册到 Spring 的 IoC 容器,方法名将默认成该 bean 定义的 id。

表达依赖注入关系层面 为了表达 bean 与 bean 之间的依赖关系,在 XML 形式中一般是这样:

<bean id="mockService" class="..MockServiceImpl"><propery name ="dependencyService" ref="dependencyService" />
</bean><bean id="dependencyService" class="DependencyServiceImpl"></bean>

而基于 JavaConfig 的配置形式是这样的:

@Configuration
public class MockConfiguration{@Beanpublic MockService mockService(){return new MockServiceImpl(dependencyService());}@Beanpublic DependencyService dependencyService(){return new DependencyServiceImpl();}
}

@ComponentScan:


@ComponentScan注解用于指定Spring容器扫描组件的基础包路径。它会自动扫描指定包及其子包下的类,并将被@Component及其派生注解标注的类识别为Spring的组件,将其实例化并纳入容器管理。

// 在包com.example中定义了两个被@Component注解标记的类:UserService和UserRepository// UserService.java
package com.example;import org.springframework.stereotype.Component;@Component
public class UserService {// ...
}// UserRepository.java
package com.example;import org.springframework.stereotype.Component;@Component
public class UserRepository {// ...
}// AppConfig.java
package com.example;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;@Configuration
@ComponentScan("com.example") // 指定扫描的基础包路径
public class AppConfig {// 配置其他的Bean
}

@ComponentScan的原理可以从源代码的角度来解释。在Spring的源代码中,@ComponentScan注解被解析为一个Bean扫描器。当Spring容器启动时,扫描器会根据指定的包路径,将带有@Component及其派生注解的类解析为BeanDefinition对象,并注册到BeanFactory中。这样,Spring容器就知道这些类是组件,并可以对其进行实例化和管理。

 

@EnableAutoConfiguration:


@EnableAutoConfiguration注解用于启用Spring Boot的自动配置功能。它会根据项目的依赖和配置,自动加载和配置一系列的Spring Bean,简化了项目的配置过程。

@EnableAutoConfiguration的原理可以从源代码的角度来解释。在Spring Boot的源代码中,@EnableAutoConfiguration注解被解析为一个自动配置处理器。当Spring Boot应用启动时,处理器会根据classpath下的META-INF/spring.factories文件中的配置,加载并执行一系列的自动配置类。这些自动配置类根据约定和条件,自动创建和配置相应的Bean对象,完成项目的自动化配置。

Import(AutoConfigurationImportSelector.class)注解:

4645b32fc9024aff95da548d4c880141.png

图中看出 AutoConfigurationImportSelector 继承了 DeferredImportSelector 继承了 ImportSelector

ImportSelector有一个方法为:selectImports。

@Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return NO_IMPORTS;}AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);AnnotationAttributes attributes = getAttributes(annotationMetadata);List<String> configurations = getCandidateConfigurations(annotationMetadata,attributes);configurations = removeDuplicates(configurations);Set<String> exclusions = getExclusions(annotationMetadata, attributes);checkExcludedClasses(configurations, exclusions);configurations.removeAll(exclusions);configurations = filter(configurations, autoConfigurationMetadata);fireAutoConfigurationImportEvents(configurations, exclusions);return StringUtils.toStringArray(configurations);}

AutoConfigurationImportSelector是Spring Boot内部的一个选择器类,它会根据项目的依赖和配置,选择要自动配置的类。该选择过程是基于条件注解(如@ConditionalOnClass、@ConditionalOnProperty等)进行的,只有满足条件的自动配置类才会被选择。

 

@AutoConfigurationPackage

// 在包com.example中定义了一个主配置类ApplicationConfig// ApplicationConfig.java
package com.example;import org.springframework.boot.autoconfigure.AutoConfigurationPackage;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
@AutoConfigurationPackage // 标注了@AutoConfigurationPackage注解
public class ApplicationConfig {// 主配置类的内容// ...
}

当Spring Boot启动时,它会扫描并解析主配置类ApplicationConfig。在解析过程中,Spring Boot会检测到@AutoConfigurationPackage注解,并执行相应的处理。

@AutoConfigurationPackage注解被解析为一个特殊的Bean定义处理器。处理器会读取主配置类ApplicationConfig的包路径(com.example),并将该包路径注册到Spring的BeanFactory中。

注册完成后,Spring容器会将com.example包及其子包作为组件扫描的范围。这意味着Spring会扫描该包下的所有类,并根据条件注解(如@ConditionalOnClass@ConditionalOnMissingBean等)来决定是否自动配置相应的Bean。

通过将主配置类所在的包及其子包作为自动配置的包,我们可以确保自动配置类能够正确地扫描和应用到我们的应用程序中。

 

 

 

相关文章:

拆解Spring boot:Springboot为什么如此丝滑而简单?源码剖析解读自动装配

&#x1f389;&#x1f389;欢迎光临&#xff0c;终于等到你啦&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;持续更新的专栏《Spring 狂野之旅&#xff1a;从入门到入魔》 &a…...

中国银行信息系统应用架构发展历程

概述&#xff1a; 从 20 世纪 80 年代开始至今&#xff0c;我国银行业信息化历程已 有四十年历史。虽然相对于发达国家来讲&#xff0c;我国银行业务信 息化起步较晚&#xff0c;但发展速度很快&#xff0c; 目前我国一些大型商业银行的信息化程度已经处于全球领先水平。 “银行…...

掌握Go语言:探索Go语言指针,解锁高效内存操作与动态数据结构的奥秘(19)

指针是一个变量&#xff0c;它存储了另一个变量的地址。在Go语言中&#xff0c;指针提供了直接访问内存地址的能力&#xff0c;允许程序直接操作内存&#xff0c;这在某些场景下非常有用。 Go语言指针的详细使用方法 声明指针 可以使用*符号来声明指针变量&#xff0c;例如&…...

大数据面试题 —— Zookeeper

目录 ZooKeeper 的定义ZooKeeper 的特点ZooKeeper 的应用场景你觉得Zookeeper比较重要的功能ZooKeeper 的选举机制 ***zookeeper主节点故障&#xff0c;如何重新选举&#xff1f;ZooKeeper 的监听原理 ***zookeeper集群的节点数为什么建议奇数台 ***ZooKeeper 的部署方式有哪几…...

【安全类书籍-6】僵尸网络:网络程序杀手

目录 内容 用处 下载链接 内容 这本书着重探讨以下几个主题: 1. 僵尸网络基础:介绍僵尸网络的基本构成、运作机制以及在全球网络空间中的影响和威胁程度。 2. 僵尸网络技术剖析:详细分析僵尸网络的组件,如命令控制中心(C&C)、恶意软件传播途径、感染节点的招募和…...

文件的创建与删除

文件的创建 使用File类创建一个文件对象&#xff0c;例如&#xff1a;File filenew File("c:\\myletter" , "letter.txt"); public boolean createNewFile();/*如果c:\myletter目录中没 有名字为letter.txt文件&#xff0c;文件对象file调用createNewFil…...

图论题目集一(代码 注解)

目录 题目一&#xff1a; 题目二&#xff1a; 题目三&#xff1a; 题目四&#xff1a; 题目五&#xff1a; 题目六&#xff1a; 题目七&#xff1a; 题目一&#xff1a; #include<iostream> #include<queue> #include<cstring> using namespace st…...

解释MVC和MVVM架构模式

一、解释MVC和MVVM架构模式 MVC和MVVM都是常见的前端架构模式&#xff0c;用于抽象分离并解决特定问题。这两种模式在结构上具有一定的相似性&#xff0c;但在细节和数据处理方式上存在一些差异。 MVC&#xff0c;即Model-View-Controller&#xff0c;是一种用于应用程序分层…...

OLLAMA:如何像云端一样运行本地大语言模型

简介&#xff1a;揭开 OLLAMA 本地大语言模型的神秘面纱 您是否曾发现自己被云端语言模型的网络所缠绕&#xff0c;渴望获得更本地化、更具成本效益的解决方案&#xff1f;那么&#xff0c;您的探索到此结束。欢迎来到 OLLAMA 的世界&#xff0c;这个平台将彻底改变我们与大型…...

React全家桶及原理解析-lesson4-Redux

lesson4-react全家桶及原理解析.mov React全家桶及原理解析 React全家桶及原理解析 课堂⽬标资源起步Reducer 什么是reducer什么是reduceRedux 上⼿ 安装reduxredux上⼿检查点react-redux 异步代码抽取Redux拓展 redux原理 核⼼实现中间件实现redux-thunk原理react-redux原理 实…...

电商api数据接口技术开发来赞达lazada通过商品ID抓取商品详情信息item_get请求key接入演示

要获取Lazada的商品详情&#xff0c;你需要使用item_get请求。首先&#xff0c;你需要注册一个开发者账号并获取API密钥&#xff08;App Key和App Secret&#xff09;。然后&#xff0c;你可以使用以下Python代码示例来获取商品详情&#xff1a; # coding:utf-8 ""&…...

零基础入门多媒体音频(2)-音频焦点2

说实话&#xff0c;android的代码是越来越难以阅读。业务函数里面狗皮膏药似的补丁与日俱增。继上篇简要介绍音频焦点的文章&#xff0c;这篇文章的主要内容是分析audiofocus的实现。看了一下午的相关代码都没找到做audiofocus策略的核心逻辑。目前能看懂的大概包含下面两个逻辑…...

Spark杂谈

文章目录 什么是Spark对比HadoopSpark应用场景Spark数据处理流程什么是RDDSpark架构相关进程入门案例&#xff1a;统计单词数量Spark开启historyServer 什么是Spark Spark是一个用于大规模数据处理的统一计算引擎Spark一个重要的特性就是基于内存计算&#xff0c;从而它的速度…...

【PyTorch】进阶学习:一文详细介绍 torch.save() 的应用场景、实战代码示例

【PyTorch】进阶学习&#xff1a;一文详细介绍 torch.save() 的应用场景、实战代码示例 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程…...

私域流量运营的关键要素和基本步骤

解锁增长的四大关键&#xff1a; 关键要素一&#xff1a;精准营销 精准营销是私域流量运营的核心所在。通过精细化运营和个性化服务&#xff0c;企业可以将普通用户转化为忠实粉丝&#xff0c;提高用户的粘性和转化率。采用数据驱动的精准营销策略&#xff0c;深度挖掘用户需求…...

k8s部署hadoop

&#xff08;作者&#xff1a;陈玓玏&#xff09; 配置和模板参考helm仓库&#xff1a;https://artifacthub.io/packages/helm/apache-hadoop-helm/hadoop 先通过以下命令生成yaml文件&#xff1a; helm template hadoop pfisterer-hadoop/hadoop > hadoop.yaml用kube…...

deepspeed分布式训练在pytorch 扩展(PyTorch extensions)卡住

错误展示&#xff1a; Using /root/.cache/torch_extensions/py310_cu121 as PyTorch extensions root...
 Using /root/.cache/torch_extensions/py310_cu121 as PyTorch extensions root...
 错误表现&#xff1a; 出现在多卡训练过程的pytorch 扩展&#xff0c;deepspee…...

Rust 的 HashMap

在 Rust 中&#xff0c;HashMap 是一个从键&#xff08;key&#xff09;映射到值&#xff08;value&#xff09;的数据结构。它允许你以 O(1) 的平均时间复杂度存储、检索和删除键值对。HashMap 实现了 std::collections::HashMap 结构体&#xff0c;通常通过 use std::collect…...

exporter方式监控达梦数据库

蓝鲸监控 随着国产化和信创的深入&#xff0c;开始普遍使用国产化数据库–如达梦数据库&#xff0c;蓝鲸平台默认没有对其进行监控&#xff0c;但是平台了提供监控告警的能力。比如脚本采集&#xff0c;脚本的是一种灵活和快速的监控采集方式&#xff0c;不同层的监控对象都可…...

供应链安全之被忽略的软件质量管理平台安全

背景 随着我国信息化进程加速&#xff0c;网络安全问题更加凸显。关键信息基础设施和企业单位在满足等保合规的基础上&#xff0c;如何提升网络安全防御能力&#xff0c;降低安全事件发生概率&#xff1f;默安玄甲实验室针对SonarQube供应链安全事件进行分析&#xff0c;强调供…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

Matlab实现任意伪彩色图像可视化显示

Matlab实现任意伪彩色图像可视化显示 1、灰度原始图像2、RGB彩色原始图像 在科研研究中&#xff0c;如何展示好看的实验结果图像非常重要&#xff01;&#xff01;&#xff01; 1、灰度原始图像 灰度图像每个像素点只有一个数值&#xff0c;代表该点的​​亮度&#xff08;或…...

ThreadLocal 源码

ThreadLocal 源码 此类提供线程局部变量。这些变量不同于它们的普通对应物&#xff0c;因为每个访问一个线程局部变量的线程&#xff08;通过其 get 或 set 方法&#xff09;都有自己独立初始化的变量副本。ThreadLocal 实例通常是类中的私有静态字段&#xff0c;这些类希望将…...

Python爬虫实战:研究Restkit库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的有价值数据。如何高效地采集这些数据并将其应用于实际业务中,成为了许多企业和开发者关注的焦点。网络爬虫技术作为一种自动化的数据采集工具,可以帮助我们从网页中提取所需的信息。而 RESTful API …...

NineData数据库DevOps功能全面支持百度智能云向量数据库 VectorDB,助力企业 AI 应用高效落地

NineData 的数据库 DevOps 解决方案已完成对百度智能云向量数据库 VectorDB 的全链路适配&#xff0c;成为国内首批提供 VectorDB 原生操作能力的服务商。此次合作聚焦 AI 开发核心场景&#xff0c;通过标准化 SQL 工作台与细粒度权限管控两大能力&#xff0c;助力企业安全高效…...

GitHub 常见高频问题与解决方案(实用手册)

1.Push 提示权限错误&#xff08;Permission denied&#xff09; 问题&#xff1a; Bash Permission denied (publickey) fatal: Could not read from remote repository. 原因&#xff1a; 没有配置 SSH key 或使用了 HTTPS 而没有权限…...

Ubuntu 安装 Mysql 数据库

首先更新apt-get工具&#xff0c;执行命令如下&#xff1a; apt-get upgrade安装Mysql&#xff0c;执行如下命令&#xff1a; apt-get install mysql-server 开启Mysql 服务&#xff0c;执行命令如下&#xff1a; service mysql start并确认是否成功开启mysql,执行命令如下&am…...

基于机器学习的智能故障预测系统:构建与优化

前言 在现代工业生产中&#xff0c;设备故障不仅会导致生产中断&#xff0c;还会带来巨大的经济损失。传统的故障检测方法依赖于人工巡检和定期维护&#xff0c;这种方式效率低下且难以提前预测潜在故障。随着工业物联网&#xff08;IIoT&#xff09;和机器学习技术的发展&…...