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

SpringBoot自动装配介绍

aa2d47c285af433a80dba4ec4454759f.jpgSpringBoot是对Spring的一种扩展,其中比较重要的扩展功能就是自动装配:通过注解对常用的配置做默认配置,简化xml配置内容。本文会对Spring的自动配置的原理和部分源码进行解析,本文主要参考了Spring的官方文档。

 

 

自动装配的组件

SpringBoot自动装配通过多部分组件协调完成,这些组件主要有下面几种,这几种组件之间协调工作,最终完成了SpringBoot的自动装配。

 

@EnableAutoConfiguration:用于根据用户所引用的jar包自动装配Spring容器,比如用户在ClassPath中包含了HSQLDB,但是没有手动配置数据库连接,那么Spring会自动使用HSQLDB作为数据源。

@Condition:不同情况下按照条件进行装配,Spring的JdbcTemplate是不是在Classpath里面?如果是,并且DataSource也存在,就自动配置一个JdbcTemplate的Bean

@ComponentScan:扫描指定包下面的@Component注解的组件。

@EnableAutoConfiguration注解

Spring的自动装配发展大致可以分为三个阶段:

 

全手工配置的XML文件阶段,用户需要的Bean全部需要在XML文件中声明,用户手工管理全部的Bean。

半手工配置的注解阶段,用户可以安装需求Enable对应的功能模块,如添加@EnableWebMvc可以启用MVC功能。

全自动配置的SpringBoot,用户只需要引入对应的starter包,Spring会通过factories机制自动装配需要的模块。

全手工配置的XML文件示意图:

 

xml手工装配

 

半自动注解配置示意图:

 

半自动配置

 

全自动注解配置示意图:

 

全自动配置

 

Spring启用全自动配置功能的注解就是@EnableAutoConfiguration,应用添加了@EnableAutoConfiguration注解之后,会读取所有jar包下面的spring.factories文件,获取文件中配置的自动装配模块,然后去装配对应的模块。

 

@EnableAutoConfiguration的功能可总结为:使Spring启用factories机制导入各个starter模块的配置。

 

原理分析

通过上面的分析我们知道Spring的@EnableAutoConfiguration主要功能是使Spring启用factories机制导入各个starter模块的配置。下面我们会对@EnableAutoConfiguration的源码进行简单分析。

 

@Target({ElementType.TYPE})

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Inherited

@AutoConfigurationPackage

@Import({AutoConfigurationImportSelector.class})

public @interface EnableAutoConfiguration {

    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

 

    Class<?>[] exclude() default {};

 

    String[] excludeName() default {};

}

@EnableAutoConfiguration注解的定义有两部分比较重要的内容:

@AutoConfigurationPackage:将添加该注解的类所在的package作为自动配置package进行管理。

@Import({AutoConfigurationImportSelector.class}):用于导入factories文件中的AutoConfiguration。

 

@Import({AutoConfigurationImportSelector.class})

首先我们需要知道@Import注解的作用,从字面意思就可以看出来,@Import用于把一个Bean注入到Spring的容器中,@Import可以导入三种类型的Bean:

 

导入普通的Bean,通常是@Configuration注解的Bean,也可以是任意的@Component组件类型的类。

导入实现了ImportSelector接口的Bean,ImportSelector接口可以根据注解信息导入需要的Bean。

导入实现了ImportBeanDefinitionRegistrar注解的Bean, ImportBeanDefinitionRegistrar接口可以直接向容器中注入指定的Bean。

@Import({AutoConfigurationImportSelector.class})中的AutoConfigurationImportSelector实现了ImportSelector接口,会按照注解内容去装载需要的Bean。

 

    public String[] selectImports(AnnotationMetadata annotationMetadata) {

        if (!this.isEnabled(annotationMetadata)) {

            return NO_IMPORTS;

        } else {

            // 获取需要自动装配的AutoConfiguration列表

            AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);

            // 获取自动装配类的类名称列表

            return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());

        }

    }

 

    // 获取需要自动装配的AutoConfiguration列表

    protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {

        if (!this.isEnabled(annotationMetadata)) {

            return EMPTY_ENTRY;

        } else {

            // 获取注解中的属性

            AnnotationAttributes attributes = this.getAttributes(annotationMetadata);

 

            // 获取所有META-INF/spring.factories中的AutoConfiguration类

            List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);

 

            // 删除重复的类

            configurations = this.removeDuplicates(configurations);

 

            // 获取注解中Execlud的类

            Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);

            this.checkExcludedClasses(configurations, exclusions);

 

            // 移除所有被Exclude的类

            configurations.removeAll(exclusions);

 

            // 使用META-INF/spring.factories中配置的过滤器

            configurations = this.getConfigurationClassFilter().filter(configurations);

 

            // 广播相关的事件

            this.fireAutoConfigurationImportEvents(configurations, exclusions);

 

            // 返回符合条件的配置类。

            return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);

        }

    }

@AutoConfigurationPackage

@AutoConfigurationPackage用于将添加该注解的类所在的package作为自动配置package进行管理,听起来是不是和@ComponentScan功能有所重复?我们来分析一下其具体实现,可以看到这个注解依旧是通过@Import注解向容器中注册Bean。

 

@Target({ElementType.TYPE})

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Inherited

@Import({Registrar.class})

public @interface AutoConfigurationPackage {

    String[] basePackages() default {};

 

    Class<?>[] basePackageClasses() default {};

}

@AutoConfigurationPackage注解导入了Registrar.class,其本质是一个ImportBeanDefinitionRegistrar,会把当前注解类所在的包注入到Spring容器中。

 

static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {

        Registrar() {

        }

 

        public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {

            AutoConfigurationPackages.register(registry, (String[])(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames().toArray(new String[0]));

        }

 

        public Set<Object> determineImports(AnnotationMetadata metadata) {

            return Collections.singleton(new AutoConfigurationPack

相关文章:

SpringBoot自动装配介绍

SpringBoot是对Spring的一种扩展&#xff0c;其中比较重要的扩展功能就是自动装配&#xff1a;通过注解对常用的配置做默认配置&#xff0c;简化xml配置内容。本文会对Spring的自动配置的原理和部分源码进行解析&#xff0c;本文主要参考了Spring的官方文档。 自动装配的组件 …...

1400*D. Candy Box (easy version)(贪心)

3 10 9 Example input 3 8 1 4 8 4 5 6 3 8 16 2 1 3 3 4 3 4 4 1 3 2 2 2 4 1 1 9 2 2 4 4 4 7 7 7 7 output 题意&#xff1a; n个糖果&#xff0c;分为多个种类&#xff0c;要求尽可能的多选&#xff0c;并且使得不同种类的数量不能相同。 解析&#xff1a; 记录每种糖…...

设计模式-备忘录模式在Java中使用示例-象棋悔棋

场景 备忘录模式 备忘录模式提供了一种状态恢复的实现机制&#xff0c;使得用户可以方便地回到一个特定的历史步骤&#xff0c;当新的状态无效 或者存在问题时&#xff0c;可以使用暂时存储起来的备忘录将状态复原&#xff0c;当前很多软件都提供了撤销(Undo)操作&#xff0…...

用合成数据训练托盘检测模型【机器学习】

想象一下&#xff0c;你是一名机器人或机器学习 (ML) 工程师&#xff0c;负责开发一个模型来检测托盘&#xff0c;以便叉车可以操纵它们。 ‌你熟悉传统的深度学习流程&#xff0c;已经整理了手动标注的数据集&#xff0c;并且已经训练了成功的模型。 推荐&#xff1a;用 NSDT设…...

人性-基本归因错误

定义 基本归因谬误指出&#xff0c;你评价别人的一个行为时&#xff0c;你会高估他的内部因素——比如性格的影响&#xff0c;低估外在的情景之类各种复杂因素的影响。 具体表现是对自己&#xff0c;我们很愿意分析复杂的原因&#xff1b;对别人&#xff0c;如果他一句话说的…...

游戏引擎:打造梦幻游戏世界的秘密武器

介绍 游戏引擎是游戏开发中不可或缺的工具&#xff0c;它为开发者提供了构建游戏世界所需的各种功能和工具。本文将介绍游戏引擎的概念、使用方法以及一个完整的游戏项目示例。 游戏引擎的概念 游戏引擎是一种软件框架&#xff0c;它提供了游戏开发所需的各种功能和工具&…...

ClickHouse(六):Clickhouse数据类型-1

进入正文前&#xff0c;感谢宝子们订阅专题、点赞、评论、收藏&#xff01;关注IT贫道&#xff0c;获取高质量博客内容&#xff01; &#x1f3e1;个人主页&#xff1a;含各种IT体系技术&#xff0c;IT贫道_Apache Doris,Kerberos安全认证,大数据OLAP体系技术栈-CSDN博客 &…...

【Linux】网络基础

&#x1f34e;作者&#xff1a;阿润菜菜 &#x1f4d6;专栏&#xff1a;Linux系统网络编程 文章目录 一、协议初识和网络协议分层&#xff08;TCP/IP四层模型&#xff09;认识协议TCP/IP五层&#xff08;或四层&#xff09;模型 二、认识MAC地址和IP地址认识MAC地址认识IP地址认…...

小程序-接口概率性接收不到参数

在小程序上调用一个接口&#xff0c;传入筛选条件&#xff0c;但返回结果却没有进行筛选&#xff0c;概率性出现这种情况&#xff0c;频率较低。 然后在postman调用该接口&#xff0c;调用很多很多次&#xff0c;发现也出现这种问题&#xff0c;看了代码&#xff0c;接口的传参…...

合作客户销售数据可视化分析

以一个案例进行实际分析&#xff1a; 数据来源&#xff1a;【地区数据分析】 以此数据来制作报表。 技巧一&#xff1a;词云图 以城市名称来显示合同金额的分布&#xff0c;合同金额越大&#xff0c;则城市文字显示越大。 技巧二&#xff1a;饼图 下面制定一个&#xff0c;合…...

git仓库迁移场景

1.git仓库迁移 代码仓库从公网迁移内网&#xff0c;内外网网络不通&#xff0c;而且必须保证代码完整&#xff0c;包括分支以及提交记录。具体步骤如下 1.1 拉取所有分支镜像 1.2 现在本地电脑新建文件夹 mkdir newdir1.3 进入新建文件 newdir 执行下面命令拉取所有镜像代码…...

【RabbitMQ】之持久化机制

目录 一、RabbitMQ 持久化机制 1、RabbitMQ 持久化概述2、队列持久化3、消息持久化4、交换器持久化 二、RabbitMQ 知识扩展 1、内存告警与内存换页2、磁盘告警与配置3、数据写入磁盘时机4、磁盘消息格式5、磁盘文件删除机制 一、RabbitMQ 持久化机制 1、RabbitMQ 持久化概述…...

【项目6 UI Demo】前端代码记录

前端代码记录 1.GridListItem中的布局 在这个Item中的布局采用的是VBox和HBox相结合的方式。相关的代码如下&#xff1a; <VBox class"sapUiTinyMargin"><HBox justifyContent"SpaceBetween"><Titletext"{ToolNumber}"wrapping…...

【计算机网络】应用层协议 -- HTTP协议

文章目录 1. 认识HTTP协议2. 认识URL3. HTTP协议格式3.1 HTTP请求协议格式3.2 HTTP响应协议格式 4. HTTP的方法5. HTTP的状态码6. HTTP的Header7. Cookie和Session 1. 认识HTTP协议 协议。网络协议的简称&#xff0c;网络协议是通信计算机双方必须共同遵守的一组约定&#xff0…...

了解Unity编辑器之组件篇Layout(八)

Layout&#xff1a;用于管理和控制UI元素的排列和自动调整一、Aspect Ratio Fitter&#xff1a;用于根据宽高比自动调整UI元素的大小 Aspect Mode&#xff1a;用于定义纵横比适配的行为方式。Aspect Mode属性有以下几种选项&#xff1a; &#xff08;1&#xff09;None&#xf…...

如何使用Flask-Mail来发送电子邮件

你知道如何使用Flask-Mail来发送电子邮件吗 Flask-Mail是一个用于Flask框架的扩展&#xff0c;它简化了在Flask应用程序中发送电子邮件的过程。通过使用Flask-Mail&#xff0c;你可以轻松地创建邮件消息对象&#xff0c;设置发件人、收件人、主题和正文&#xff0c;并使用SMTP服…...

【笔记】Java并发编程

为什么不建议使用Executors创建线程池分析 不建议使用Executors来创建线程池&#xff0c;主要是有两大原因第一个是问题回溯的问题&#xff0c;使用Executors都可以使用默认的情况&#xff0c;无法用户自定义线程名称不利于排查问题&#xff0c;第二个原因也是最主要原因就是线…...

Hive内部表和外部表

表类型详解 表分类 在Hive中,表类型主要分为两种 第一种&#xff1a;内部表 也叫管理表表目录会创建在集群上的{hive.metastore.warehouse.dir}下的相应的库对应的目录中。默认创建的表就是内部表 第二种&#xff1a;外部表 外部表需要使用关键字"external"&#xff…...

【面试题】与通义千问的芯片前端设计模拟面试归纳

这里是尼德兰的喵芯片设计相关文章,欢迎您的访问! 如果文章对您有所帮助,期待您的点赞收藏! 让我们一起为芯片前端全栈工程师而努力! 前言 两个小时,与chatGPT进行了一场数字IC前端设计岗的面试_尼德兰的喵的博客-CSDN博客 和GPT-3.5的回答可以对比品尝,味道更好。 模…...

无法加载文件 C:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本。npm.ps1 cannot be loaded

目录 原因 解决方法 提示 查看当前的执行策略命令 改回默认值 "Restricted"命令 这个错误提示是因为您的系统禁止执行 PowerShell 脚本。 原因 现用执行策略是 Restricted&#xff08;默认设置&#xff09; 解决方法 以管理员身份运行 PowerShell&#xff1a;右键…...

数据鲸鱼具身智能task3

我的理解&#xff1a;模型广场提供了模型的雏形与底座&#xff0c;是一些已经85分的通用模型&#xff0c;各任务可以基于这里的模型去试验&#xff0c;根据试验的结果&#xff08;这里就到了数据管理&#xff09;发现数据的偏向或侧重点不同&#xff0c;根据这种数据的表现差异…...

JMeter接口断言实战:从响应匹配到业务逻辑校验

1. 断言不是“加个勾就完事”的装饰品&#xff0c;而是接口测试的判决书很多人第一次在JMeter里点开“添加 → 断言 → 响应断言”&#xff0c;填上一个“包含文本&#xff1a;success”&#xff0c;跑完看绿色小对勾亮了&#xff0c;就以为测试通过了——结果上线后接口明明返…...

陆渔科技投入三千万学费:用AI擦去水产养殖不确定性,带来养殖确定性

创业故事&#xff1a;从偶然入局到屡败屡战陆渔科技深耕农业AI&#xff0c;两次失败、投入三千万学费&#xff0c;才拿到这张真实的“入场券”。鲁敏等四人原本与农业毫无关联&#xff0c;一次偶然饭局结识养鱼伙伴&#xff0c;了解到鲈鱼苗孵化项目。当时互联网、房地产市场饱…...

CANN 算子调优:榨干昇腾硬件性能

一、算子性能分析基础 1.1 算子执行模型 昇腾上每个算子的执行都会经历&#xff1a;编译时优化 → 运行时调度 → 硬件执行。任何一个环节出问题都会导致性能下降。 ┌────────────────────────────────────────┐ │ 算子执…...

揭秘Midjourney V6蒸汽波出图失败率高达63%的底层原因:3步绕过平台封禁,稳定生成霓虹故障美学

更多请点击&#xff1a; https://codechina.net 第一章&#xff1a;蒸汽波美学的数字幽灵&#xff1a;Midjourney V6封禁机制本质解构 蒸汽波&#xff08;Vaporwave&#xff09;以低保真采样、CRT扫描线、80年代商业图腾与数字怀旧为视觉语法&#xff0c;其美学内核恰恰在于对…...

远程会议还在发文档改来改去?我用 Rustpad 搭了个协作平台彻底解决

前言 远程会议开到一半&#xff0c;需要共同修订一份文档或代码提纲&#xff0c;这种场景估计不少人经历过。方案来来去去就那几个&#xff1a;发邮件等反馈、微信来回传文件、用腾讯文档但要登录账号……每种都有各自的鸡肋之处。后来我自己琢磨出一套更顺手的方案&#xff1…...

如何安全提取未知文件:unblob的5大安全防护机制实战指南

如何安全提取未知文件&#xff1a;unblob的5大安全防护机制实战指南 【免费下载链接】unblob Extract files from any kind of container formats 项目地址: https://gitcode.com/gh_mirrors/un/unblob 在数字取证和固件分析工作中&#xff0c;我们经常需要处理来源不明…...

10个Elog实用技巧:让你的博客管理效率翻倍

10个Elog实用技巧&#xff1a;让你的博客管理效率翻倍 【免费下载链接】elog Markdown 批量导出工具、开放式跨平台博客解决方案&#xff0c;随意组合写作平台(语雀/Notion/FlowUs/飞书/我来Wolai)和博客平台(Hexo/Vitepress/Halo/Confluence/WordPress等) 项目地址: https:/…...

AI+HR 全生命周期智能管理实战指南:从概念到落地,解锁组织效能新增长!​

在企业数字化转型的浪潮中&#xff0c;人力资源管理正经历着前所未有的变革。据行业数据&#xff0c;61% 的 HR 领导者已进入 GenAI 实施进阶阶段&#xff0c;82% 的企业计划在 12 个月内部署 AI 智能体&#xff0c;而 AI 驱动的企业人均效能已实现3.2 倍提升。当传统 HR 深陷事…...

2026年数字孪生升级版:三维重构透明建筑实时重构跟踪定位

2026数字孪生升级&#xff1a;三维重构透明建筑实时重构跟踪定位结合2026年数字孪生技术前沿迭代趋势&#xff0c;围绕实景三维重构、建筑透明可视化、场景实时重构、全域跟踪定位四大核心能力&#xff0c;完成新一代数字孪生体系技术升级。彻底解决传统数字孪生静态滞后、建筑…...