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

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

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

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

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

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

努力的苏泽icon-default.png?t=N7T8http://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为何那么强大

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

解读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{
    @Bean
    public 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{
    @Bean
    public MockService mockService(){
        return new MockServiceImpl(dependencyService());
    }

    @Bean
    public 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)注解:

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

ImportSelector有一个方法为:selectImports。

@Override
    public 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。

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Screaming Frog SEO Spider:网站优化利器,轻松掌握网络爬虫精髓

在数字时代&#xff0c;网络爬虫已成为各行各业获取数据、分析趋势的重要工具。而在众多网络爬虫开发工具中&#xff0c;Screaming Frog SEO Spider以其强大的功能和易用性脱颖而出&#xff0c;成为众多网站优化师和SEO从业者的首选。 Screaming Frog SEO Spider是一款适用于M…

笔记本电脑数据恢复:如何轻松地从笔记本电脑恢复文件

不小心从笔记本电脑中删除了一些重要文件&#xff1f;或者恶意软件和其他不可控因素是否导致您的文件消失&#xff1f;人们很容易认为这些文件已经永远消失&#xff0c;并且无法恢复。但这与事实相差甚远。通过遵循正确的数据恢复礼仪并使用良好的数据恢复工具&#xff0c;您可…

英语翻译报价,千字英语翻译报价

众所周知&#xff0c;英语作为全球通用的语言&#xff0c;其翻译需求量极大。无论是欧美国家的日常交流&#xff0c;还是小语种的翻译工作&#xff0c;英语都常常作为中介语言&#xff0c;扮演着桥梁的角色。那么&#xff0c;英语翻译公司是如何定价的&#xff1f;每千字的英语…

Qt中进行客户端开发框架

在Qt中进行客户端开发是一种常见的做法&#xff0c;Qt是一个跨平台的C框架&#xff0c;提供了丰富的工具和类库&#xff0c;用于开发图形用户界面&#xff08;GUI&#xff09;应用程序、网络应用程序以及其他类型的软件。以下是一些常用的Qt客户端开发框架和技术&#xff0c;希…

Exam in MAC [容斥]

题意 思路 正难则反 反过来需要考虑的是&#xff1a; (1) 所有满条件一的(x,y)有多少对&#xff1a; x 0 时&#xff0c;有c1对 x 1 时&#xff0c;有c对 ...... x c 时&#xff0c;有1对 以此类推 一共有 (c2)(c1)/2 对 (2) 符合 x y ∈ S的有多少对&#xff1a…

Qt客户端开发的技术难点

在Qt客户端开发中&#xff0c;可能会遇到一些技术难点&#xff0c;这些难点可能与UI设计、性能优化、跨平台兼容性等方面有关。以下是一些可能的技术难点&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作…

虚拟游戏理财 - 华为OD统一考试(C卷)

OD统一考试&#xff08;C卷&#xff09; 分值&#xff1a; 100分 题解&#xff1a; Java / Python / C 题目描述 在一款虚拟游戏中生活&#xff0c;你必须进行投资以增强在虚拟游戏中的资产以免被淘汰出局。 现有一家Bank&#xff0c;它提供有若干理财产品m&#xff0c;风险及…

将SQL数据库转换为Mysql数据库

一、准备工作 1、SQL server安装包与已经有数据的mdf、ldf数据库文件&#xff1b; 2、.net Framework安装包&#xff1b;&#xff08;用于支持SQL Server安装的组件&#xff09; 3、MySql安装包&#xff1b;&#xff08;用于目标数据库的环境安装&#xff09; 4、navicat安装包…

YOLOv8旋转目标检测实战:训练自己的数据集

课程链接&#xff1a;https://edu.csdn.net/course/detail/39393 旋转目标检测是计算机视觉领域的一个高级任务&#xff0c;它在传统目标检测的基础上进一步发展。传统目标检测技术主要关注于识别和定位图像中的物体&#xff0c;通常以水平边界框(HBB)来标识目标物体的位置。而…

SpringBoot高级

1.自动配置-Condition Condition是Spring4.0后引入的条件化配置接口&#xff0c;通过实现Condition接口可以完成有条件的加载相应的Bean 进入 SpringBoot 启动类&#xff0c;点击进入 run() 可以看到这个方法是有返回值的&#xff0c;返回值为 ConfigurableApplicationConte…

[Redis]——主从同步原理(全量同步、增量同步)

目录 Redis集群&#xff1a; 主从同步原理&#xff1a; replid和offset: 全量同步和增量同步&#xff1a; repl_baklog文件&#xff1a; 主从集群的优化&#xff1a; Redis集群&#xff1a; 部署多台Redis我们称之为Redis集群&#xff0c;他有一个主节点(负责写操作)&…

什么是施密特触发器?一文详解

施密特触发器的定义 施密特触发器&#xff08;Schmitt Trigger&#xff09;是一种电子电路&#xff0c;常用于数字逻辑电路和信号处理电路中。它具有两个不同的阈值电压级别&#xff0c;通过这些不同的电压级别&#xff0c;可以将输入信号转换为相对稳定的输出信号。 当输入信…

【Datawhale组队学习:Sora原理与技术实战】使用KAN-TTS合成女生沪语音频

Sambert-Hifigan模型介绍 拼接法和参数法是两种Text-To-Speech(TTS)技术路线。近年来参数TTS系统获得了广泛的应用&#xff0c;故此处仅涉及参数法。 参数TTS系统可分为两大模块&#xff1a;前端和后端。 前端包含文本正则、分词、多音字预测、文本转音素和韵律预测等模块&am…

Django之Form组件

Django之Form组件 目录 Django之Form组件介绍手动渲染错误信息基于Form组件校验数据重写错误信息用户名与密码radioSelect单选Select多选Select单选checkbox多选checkbox 前端渲染 介绍 Form组件提供了一种在网页上收集用户输入数据并将其提交到服务器进行处理的机制&#xff…

实战纪实 | 记一次绕过宝塔的的文件上传

前几天找到个可以上传任意文件的上传点&#xff0c;成功上传phpinfo页面并能访问&#xff0c;但是不能成功上传一句话&#xff0c;发现这台主机装了宝塔&#xff0c;经过反复尝试终于成功上传一句话并连接。 0x01 漏洞发现 结果前期摸索&#xff0c;发现了一个上传点&#xff0…

Java中 常见的开源树库介绍

阅读本文之前请参阅------Java中 树的基础知识介绍 在 Java 中&#xff0c;有几种流行的开源树库&#xff0c;它们提供了丰富的树算法和高级操作&#xff0c;可以帮助开发者更高效地处理树相关的问题。以下是几种常见的 Java 树库及其特点和区别&#xff1a; JTree 特点…

一场“猜成绩”大赛:ArrayList vs. LinkedList

今天我们将带来一场精彩绝伦的较量——ArrayList对阵LinkedList。 ArrayList它就像是一张大桌子&#xff0c;可以容纳各种各样的物品。 ArrayList是一个动态数组&#xff0c;具有随机访问的能力&#xff0c;这意味着我们可以在O(1)的时间复杂度内访问任意位置的元素。 它还具…

从零开始的LLaMA-Factory的指令增量微调

大模型相关目录 大模型&#xff0c;包括部署微调prompt/Agent应用开发、知识库增强、数据库增强、知识图谱增强、自然语言处理、多模态等大模型应用开发内容 从0起步&#xff0c;扬帆起航。 大模型应用向开发路径及一点个人思考大模型应用开发实用开源项目汇总大模型问答项目…

TinTin Web3 动态精选:以太坊坎昆升级利好 Layer2,比特币减半进入倒计时

TinTin 快讯由 TinTinLand 开发者技术社区打造&#xff0c;旨在为开发者提供最新的 Web3 新闻、市场时讯和技术更新。TinTin 快讯将以周为单位&#xff0c; 汇集当周内的行业热点并以快讯的形式排列成文。掌握一手的技术资讯和市场动态&#xff0c;将有助于 TinTinLand 社区的开…

促合作 | 遵义医科大学珠海校区老师一行莅临全视通参观交流

近日&#xff0c;遵义医科大学珠海校区&#xff08;简称“遵医”&#xff09;护理学系副主任李佳、大学生创新创业中心主任王燕&#xff0c;携同校内多位教师&#xff0c;共赴珠海全视通信息技术有限公司&#xff08;简称“全视通”&#xff09;进行参观交流。此次来访旨在深化…