Springboot基础篇(4):自动配置原理

1 自动配置原理剖析

1.1 加载配置类的源码追溯

  1. 自动配置的触发入口: @SpringBootApplication 组合注解是自动配置的起点,其核心包含 @EnableAutoConfiguration,该注解使用AutoConfigurationImportSelector 实现配置类的动态加载。

ALt

启动类的注解@SpringBootApplication

//可以应用于类、接口(包括注解类型)和枚举声明
@Target(ElementType.TYPE)
//注解信息将在运行时保留
@Retention(RetentionPolicy.RUNTIME)
//在使用 Javadoc 工具生成 API 文档时,该注解将被包含在文档中
@Documented
//如果一个类使用了@SpringBootApplication 注解,那么它的子类也会继承这个注解
@Inherited
//springboot配置类
@SpringBootConfiguration
//核心:启用Spring Boot 的自动配置机制
@EnableAutoConfiguration
//启用组件扫描
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication{}
@SpringBootApplication注解
  1. 查看@EnableAutoConfiguration,@EnableAutoConfiguration注解上导入了AutoConfigurationImportSelector.class,该类负责选择和导入需要自动配置的类
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
//指定自动配置的包路径,通常用于扫描带有@Configuration 注解的类
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {}
3 @EnableAutoConfiguration注解
  1. 查看AutoConfigurationImportSelector.class,该类负责加载、筛选和返回需要加载的自动配置类
public class AutoConfigurationImportSelector implements ... {// 核心方法:选择并加载自动配置类
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {// 1. 检查是否启用自动配置if (!isEnabled(annotationMetadata)) {return NO_IMPORTS; // 如果未启用,返回空数组}// 2. 获取自动配置条目AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);// 3. 返回配置类数组return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
  1. 查看selectImports中调用的getAutoConfigurationEntry方法。
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {// 1. 检查是否启用自动配置if (!isEnabled(annotationMetadata)) {return EMPTY_ENTRY; // 如果未启用,返回空条目}// 2. 获取注解属性AnnotationAttributes attributes = getAttributes(annotationMetadata);// 3. 加载候选配置类List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);// 4. 去重configurations = removeDuplicates(configurations);// 5. 获取排除项Set<String> exclusions = getExclusions(annotationMetadata, attributes);// 6. 检查排除项checkExcludedClasses(configurations, exclusions);// 7. 过滤排除项configurations.removeAll(exclusions);// 8. 应用配置类过滤器configurations = getConfigurationClassFilter().filter(configurations);// 9. 触发事件fireAutoConfigurationImportEvents(configurations, exclusions);// 10. 返回结果return new AutoConfigurationEntry(configurations, exclusions);
}
  1. 查看getAutoConfigurationEntry方法调用的getCandidateConfigurations方法
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {// 1. 加载候选配置类ImportCandidates importCandidates = ImportCandidates.load(this.autoConfigurationAnnotation, getBeanClassLoader());List<String> configurations = importCandidates.getCandidates();// 2. 检查配置类是否为空Assert.notEmpty(configurations,"No auto configuration classes found in " + "META-INF/spring/"+ this.autoConfigurationAnnotation.getName() + ".imports. If you "+ "are using a custom packaging, make sure that file is correct.");// 3. 返回配置类列表return configurations;
}
  1. 查看getCandidateConfigurations调用的load方法,可以看到该方法负责从类路径中加载指定注解对应的 .imports 文件,并解析文件内容。
public static ImportCandidates load(Class<?> annotation, ClassLoader classLoader) {// 1. 检查注解是否为空Assert.notNull(annotation, "'annotation' must not be null");// 2. 决定类加载器ClassLoader classLoaderToUse = decideClassloader(classLoader);// 3. 构建文件路径String location = String.format("META-INF/spring/%s.imports", annotation.getName());// 4. 查找文件 URLEnumeration<URL> urls = findUrlsInClasspath(classLoaderToUse, location);// 5. 读取文件内容List<String> importCandidates = new ArrayList<>();while (urls.hasMoreElements()) {URL url = urls.nextElement();importCandidates.addAll(readCandidateConfigurations(url));}// 6. 返回结果return new ImportCandidates(importCandidates);
}
  1. 最后我们终于知道,@SpringBootApplication通过层层修饰,最后到了load方法,load方法扫描并读取类路径下的.imports文件中的配置类。

1.2 通过条件注解注册配置类

我们选择mybatis的包来介绍如何注册的

  1. 找到mybatis的自动配置包在这里插入图片描述

  2. 查看.imports文件
    在这里插入图片描述

  3. 查看部分配置类:这个类的含义是在满足以下条件时,自动配置并注册一个 FreeMarkerLanguageDriver Bean:
    a、 类路径中存在 FreeMarkerLanguageDriver 和 FreeMarkerLanguageDriverConfig 类。
    b、 Spring 容器中尚未注册 FreeMarkerLanguageDriver 类型的 Bean。

  @Configuration(proxyBeanMethods = false)@ConditionalOnClass({ FreeMarkerLanguageDriver.class, FreeMarkerLanguageDriverConfig.class })public static class FreeMarkerConfiguration {@Bean@ConditionalOnMissingBeanFreeMarkerLanguageDriver freeMarkerLanguageDriver(FreeMarkerLanguageDriverConfig config) {return new FreeMarkerLanguageDriver(config);}
org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration配置类的Bean

2 案例:自定义一个自动配置类

  1. 需求:写一个自动配置类,当访问http://localhost:8080/sayhello时,使用控制器使用自动配置类去打印“HELLO!”
  2. 创建业务类
public class GreetingService {private String message = "Hello!";public String sayHello() {return message;}// 支持自定义问候语public void setMessage(String message) {this.message = message;}
}
  1. 创建业务自动配置类
@Configuration
public class GreetingServiceAutoConfiguration {@Beanpublic GreetingService greetingService() {return new GreetingService();}
}
  1. 注册配置
    ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/a6a07b374504405bb2f2afef1d91548a.png

  2. 编写控制器

@RestController
public class HelloController {@Autowired private GreetingService service;@RequestMapping("/hello")public String hello(){return "Hello World";}@RequestMapping("/sayhello")public String sayHello(){return service.sayHello();}
}
  1. 项目结构
    在这里插入图片描述
  2. 效果图
    在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【大模型系列】开发工具Cursor使用配置及备忘

开发工具cursor使用过程的配置备忘 最近一段时间大模型开发工具cursor是比较火爆的&#xff0c;其提供的一个比较有价值的特性就是其ai辅助功能&#xff0c;其内部集成了若干大模型 提供免费使用期&#xff1b; 做大模型开发这个话题应该是绕不过的&#xff0c;就像开发java使…

vtkAppendPolyData vtkMultiBlockDataGroupFilter 区别 合并数据

Summary: vtkAppendPolyData vtkMultiBlockDataGroupFilter 区别 两个都是合并数据&#xff1b; 用于处理多块数据集的两种不同的过滤器&#xff08;filters&#xff09;&#xff0c;它们在处理和合并多块数据集方面有不同的用途和实现方式。 Part2:区别 它们的主要区别在于…

C++入门——输入输出、缺省参数

C入门——输入输出、缺省参数 一、C标准库——命名空间 std C标准库std是一个命名空间&#xff0c;全称为"standard"&#xff0c;其中包括标准模板库&#xff08;STL&#xff09;&#xff0c;输入输出系统&#xff0c;文件系统库&#xff0c;智能指针与内存管理&am…

定制开发开源AI智能名片S2B2C商城小程序:以“晒”为桥,构建信任,助力社交新零售飞跃

摘要&#xff1a;随着互联网的深入发展和社交媒体的普及&#xff0c;社交新零售逐渐成为商业领域的新热点。在这个充满机遇与挑战的时代&#xff0c;如何快速建立与陌生消费者的信任关系&#xff0c;成为决定商业成功的关键。本文将以定制开发开源AI智能名片S2B2C商城小程序为研…

【Linux】Linux Progress Pulse-进度条

> &#x1f343; 本系列为Linux的内容&#xff0c;如果感兴趣&#xff0c;欢迎订阅&#x1f6a9; > &#x1f38a;个人主页:【小编的个人主页】 >小编将在这里分享学习Linux的心路历程✨和知识分享&#x1f50d; >如果本篇文章有问题&#xff0c;还请多多包涵&a…

Zypher Network :基于零知识证明方案为 AI 赋予可信框架

Zypher Network 提出的系列方案正逐步成为破解这一困局的关键&#xff0c;其不仅为 LLM 和 AI Agent 等采用提供了一个可信的框架&#xff0c;也为其在更广泛行业中的应用铺平了道路。 LLM 的 “黑盒特性” 像 ChatGPT、DeepSeek、Grok 等大型语言模型&#xff08;LLM, Large …

从Manus到OpenManus:多智能体协作框架如何重构AI生产力?

文章目录 Manus&#xff1a;封闭生态下的通用AI智能体OpenManus&#xff1a;开源社区的闪速复刻挑战与未来&#xff1a;框架落地的现实边界当前局限性未来演进方向 OpenManus使用指南1. 环境配置2. 参数配置3. 替换搜索引擎4. 运行效果 协作框架开启AI生产力革命 Manus&#xf…

深入理解与配置 Nginx TCP 日志输出

一、背景介绍 在现代网络架构中&#xff0c;Nginx 作为一款高性能的 Web 服务器和反向代理服务器&#xff0c;广泛应用于各种场景。除了对 HTTP/HTTPS 协议的出色支持&#xff0c;Nginx 从 1.9.0 版本开始引入了对 TCP 和 UDP 协议的代理功能&#xff0c;这使得它在处理数据库…

Python - 轻量级后端框架 Flask

Flask是什么&#xff1f; Flask是一个轻量级的Python Web框架&#xff0c;用于构建Web应用程序和API。简单、灵活、易扩展&#xff0c;适合小型项目或需要快速开发的应用。 接口的输入和输出 输入&#xff1a;request GET参数、POST JSON数据、POST表单 from flask import…

<论文>MiniCPM:利用可扩展训练策略揭示小型语言模型的潜力

一、摘要 本文跟大家一起阅读的是清华大学的论文《MiniCPM: Unveiling the Potential of Small Language Models with Scalable Training Strategies》 摘要&#xff1a; 对具有高达万亿参数的大型语言模型&#xff08;LLMs&#xff09;的兴趣日益增长&#xff0c;但同时也引发…

好玩的谷歌浏览器插件-自定义谷歌浏览器光标皮肤插件-Chrome 的自定义光标

周末没有啥事 看到了一个非常有意思的插件 就是 在使用谷歌浏览器的时候&#xff0c;可以把鼠标的默认样式换一个皮肤。就像下面的这种样子。 实际谷歌浏览器插件开发对于有前端编程基础的小伙伴 还是比较容易的&#xff0c;实际也是写 html css js 。 所以这个插件使用的技术…

3.使用ElementUI搭建侧边栏及顶部栏

1. 安装ElementUI ElementUI是基于 Vue 2.0 的桌面端组件库。使用之前&#xff0c;需要在项目文件夹中安装ElementUI&#xff0c;在终端中输入以下命令&#xff0c;进行安装。 npm i element-ui -S并在main.js中引入ElementUI 2. 使用elmentUI组件进行页面布局 2.1 清空原…

调研:如何实现智能分析助手(Agent)(AutoCoder、FastGPT、AutoGen、DataCopilot)

文章目录 调研&#xff1a;如何实现智能分析助手&#xff08;Agent&#xff09;&#xff08;AutoCoder、FastGPT、AutoGen、DataCopilot&#xff09;一、交互流程二、数据流程三、架构分类四、开源产品4.1 AutoCoder&#xff08;知识库变体&#xff09;4.2 FastGPT&#xff08;…

matlab常见的配图代码实现1

1. 折线图 x linspace(0, 10, 100); y1 sin(x);y2 cos(x); figure; plot(x, y1, -o, LineWidth, 2, MarkerSize, 6, MarkerFaceColor, b); hold on;plot(x, y2, -s, LineWidth, 2, MarkerSize, 6, MarkerFaceColor, r); title(折线图); xlabel(X轴); ylabel(Y轴); legend(s…

【汇编语言】单片机程序执行过程

一、任务需求 指示灯LED4闪烁&#xff0c;亮0.5秒&#xff0c;灭0.5秒&#xff0c;无限循环 二、针对硬件的编程 1、确定原理图2、确定硬件的物理关系 三、设计步骤 1.用自己的语言描述工作流程 1.1指示灯LED4亮1.2延时0.5秒1.3指示灯LED4灭1.4延时0.5秒1.5跳转到1.1步 …

从零开始用react + tailwindcss + express + mongodb实现一个聊天程序(十二) socketio 消息处理

1.后端 在message.controller.js中 在sendMessage方法中 每当我们发送消息 需要socketio把这个消息转发给 接收人 加入转发逻辑 // 把消息发给指定的用户的socket const receiverSocketId getReceiverSocketId(receiverId); if(receiverSocketId) { io.to(receiverSocket…

【大模型】WPS 接入 DeepSeek-R1详解,打造全能AI办公助手

目录 一、前言 二、WPS接入AI工具优势​​​​​​​ 三、WPS接入AI工具两种方式 3.1 手动配置的方式 3.2 Office AI助手 四、WPS手动配置方式接入AI大模型 4.1 安装VBA插件 4.1.1 下载VBA插件并安装 4.2 配置WPS 4.3 WPS集成VB 4.4 AI助手效果测试 4.5 配置模板文…

SmolVLM2 - 将视频理解带到每个设备

本文翻译整理自&#xff1a;SmolVLM2: Bringing Video Understanding to Every Device https://huggingface.co/blog/smolvlm2 文章目录 TL;DR: SmolVLM 现在可以观看 &#x1f4fa; 并拥有更好的视觉理解一、关于 SmolVLM2二、 技术细节1、SmolVLM2 2.2B: 我们新的视觉和视频明…

Cocos Creator Shader入门实战(三):CCEffect参数配置讲解

引擎版本&#xff1a;3.8.5 您好&#xff0c;我是鹤九日&#xff01; 回顾 稍微回顾下前面两篇博客讲解的内容&#xff1a; 一、Cocos渲染效果的实现需要Material材质和Effect资源的互相配合。 二、Effect资源负责Shader片段的编写和属性配置&#xff0c;Material材质负责对E…

计算机毕业设计:公司烤箱配件质量信息追溯系统

超级管理员表创建语句如下&#xff1a; 公司烤箱配件质量信息追溯系统mysql数据库创建语句公司烤箱配件质量信息追溯系统oracle数据库创建语句公司烤箱配件质量信息追溯系统sqlserver数据库创建语句公司烤箱配件质量信息追溯系统springspringMVCmybatis框架对象(javaBean,pojo…