SpringBoot自动配置原理、手写一个xxx-spring-boot-starter

news2024/11/15 10:05:51

SpringBoot的自动配置是:当项目中使用了一个第三方依赖,如何将第三方依赖中的Bean加载到Spring的IOC容器中,我们就可以做到无需额外的配置,直接使用第三方jar中的Bean。
SpringBoot的理念是“约定大于配置”,只要按照SpringBoot约定的规则来提供第三方的jar,SpringBoot就可以自动扫描jar中的Bean加载到IOC容器中。
先要了解SpringBoot自动配置的原理,才能手写一个xxx-spring-boot-starter

SpringBoot自动配置的原理

当我们在SpringBoot的启动类上使用了@SpringBootApplication注解后,这个注解是一个复合注解

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

查看这个注解,会看见有一个@EnableAutoConfiguration的注解,这个注解是实现SpringBoot自动配置的关键注解.

@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 {  
	// ...
}

继续查看@EnableAutoConfiguration注解

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

此注解也是一个复合注解,在此注解中有一个@AutoConfigurationPackage注解,此注解能够实现此项目中启动类所在包及其子包下的Bean的自动注入
还通过@Import注解来导入一个AutoConfigurationImportSelector类,此类是实现第三方依赖中Bean注入的关键类

接下来说的是第三方依赖中要做好的配置
在第三方的依赖中,为了实现让SpringBoot自动配置本依赖,需要在此依赖中定义一个配置类,并使用@Configuration注解标注,在这个配置类中使用@Bean注解将需要注入的Bean实例化并提供出来
在此项目中的resources目录下的META-INF目录下新建spring.factories文件,此文件是一个类似于.properties的文件,通过键值对的形式,value为使用了@Configuration的配置类的全限定名
以上就是第三方依赖需要做的配置

接下来继续回到本项目,导入第三方的starter依赖后,
当项目启动后,上述的AuthoConfigurationImportSelector类就会依靠一个叫做SpringFactoriesLoader的类,此类的作用是扫描所以jar中的META-INF/spring.factories的文件,将所有文件中定义的配置类的全限定名返回,
当拿到这些第三方依赖的配置类,这些配置类中提供了要自动注入的Bean,就可以直接使用第三方依赖中的提供出来的Bean了

手写一个spring-boot-starter

1. 首先创建一个maven项目

<?xml version="1.0" encoding="UTF-8"?>  
<project xmlns="http://maven.apache.org/POM/4.0.0"  
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
    <modelVersion>4.0.0</modelVersion>  
  
    <groupId>org.liumingkai</groupId>  
    <artifactId>kkk-spring-boot-starter</artifactId>  
    <version>1.0-SNAPSHOT</version>  
  
    <dependencies>  
        <dependency>  
            <groupId>org.springframework.boot</groupId>  
            <artifactId>spring-boot-starter</artifactId>  
            <version>2.7.10</version>  
        </dependency>  
    </dependencies>  
    <properties>  
        <maven.compiler.source>8</maven.compiler.source>  
        <maven.compiler.target>8</maven.compiler.target>  
    </properties>  
  
</project>

2.创建一个需要自动注入的Bean

package com.liumingkai.service;  
  
import org.springframework.beans.factory.annotation.Value;  
  
/**  
 * @author 刘明凯  
 * @version 0.0.1  
 * @date 2023年4月23日 19:50  
 */public class SayHello {  
  
    @Value("Mingkai Liu")  
    private String name;  
  
    public void sayHello(){  
        System.out.println("Hello , My name is " +  name);  
    }  
  
}

3.创建此项目的配置类,将需要注入的类提供出去

package com.liumingkai.auto;  
  
import com.liumingkai.service.SayHello;  
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
  
/**  
 * @author 刘明凯  
 * @version 0.0.1  
 * @date 2023年4月23日 19:50  
 */@Configuration  
public class MyConfiguration {  
  
    @Bean  
    public SayHello sayHello(){  
        SayHello sayHello = new SayHello();  
        return sayHello;  
    }  
  
}

4. 在META-INF/spring.factories文件中指明该项目配置类的全限定名

org.springframework.boot.autoconfigure.EnableAutoConfiguration= com.liumingkai.auto.MyConfiguration

5.将项目打包到本地仓库(利用Maven的install命令)
6.在需要引用的项目中导入此依赖

<dependency>  
    <groupId>org.liumingkai</groupId>  
    <artifactId>kkk-spring-boot-starter</artifactId>  
    <version>1.0-SNAPSHOT</version>  
</dependency>

测试自动注入是否成功

package com.liumingkai;  
  
import com.liumingkai.service.SayHello;  
import org.junit.jupiter.api.Test;  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.boot.test.context.SpringBootTest;  
  
@SpringBootTest  
class SpringBootTestMystaterApplicationTests {  
  
    @Autowired  
    private SayHello hello;  
  
    @Test  
    void contextLoads() {  
        hello.sayHello();  
    }  
  
}

运行结果,发现成功注入

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

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

相关文章

【下载器篇】IDM下载记录分析(简)

【下载器篇】IDM下载记录分析&#xff08;简&#xff09; IDM下载记录分析-未完待续—【蘇小沐】 文章目录 【下载器篇】IDM下载记录分析&#xff08;简&#xff09;1.实验环境 &#xff08;一&#xff09;IDM下载记录分析-未完待续临时文件夹下载痕迹 总结 1.实验环境 系统版…

【内网渗透】春秋云镜Intitle WP

前言 第一次正式接触内网渗透的东西&#xff0c;写的很新手&#xff0c;也适合新手观看&#xff0c;有问题可以私信或评论&#xff0c;接下来会持续更新 信息收集 拿到地址先nmap扫端口 没什么发现&#xff0c;直接访问80端口&#xff0c;看到图标知道是thinkphp 第一台Th…

leetcode刷题(8)二叉树(2)

各位朋友们&#xff0c;大家好&#xff01;今天我为大家分享的是关于二叉树leetcode刷题的第二篇&#xff0c;我们一起来看看吧。 文章目录 1.对称二叉树题目要求示例做题思路代码实现 2.二叉树的最大深度题目要求示例做题思路代码实现 3.翻转二叉树题目要求示例做题思路代码实…

WebSocket入门

WebSocket 1.1websoket介绍 websocket是一种网络通信协议&#xff0c;RFC6455定义了它的通信标准 websocket是Html5开始提供的一种在单个TCP连接上进行全双工通讯的协议 Http协议是一种无状态、无连接、单向的应用层协议&#xff0c;它采用了请求/响应模型&#xff0c;通信…

Tomcat多实例部署实验

引言 本文主要内容是tomcat的多实例配置实验。 一、实验准备 Tomcat多实例是指在一台设备上运行多个Tomcat服务&#xff0c;这些Tomcat相互独立&#xff0c;互不影响。多实例与虚拟主机不同&#xff0c;虚拟主机的本质是在一个服务下有多个相对独立的目录&#xff0c;但是多实…

OFA(One-For-All)阿里达摩院实现架构、模态、任务的三个统一之Image Captioning

OFA(One-For-All) 通用多模态预训练模型&#xff0c;使用简单的序列到序列的学习框架统一模态&#xff08;跨模态、视觉、语言等模态&#xff09;和任务&#xff08;如图片生成、视觉定位、图片描述、图片分类、文本生成等&#xff09; 架构统一&#xff1a;使用统一的transfo…

何谓SRIO——RapidIO之旅从这里开始

何谓SRIO——RapidIO之旅从这里开始 SRIO&#xff08;Serial RapidIO&#xff09;协议是一种用于高速串行通信的协议&#xff0c;旨在连接数字信号处理器&#xff08;DSP&#xff09;、网络处理器、FPGA等芯片&#xff0c;以及它们之间的互连。SRIO协议具有低延迟、高带宽&…

【单链表】

单链表 1. 函数的声明部分2. 函数的实现部分&#xff08;1&#xff09;打印链表&#xff08;2&#xff09;头插&#xff08;3&#xff09;尾插&#xff08;3&#xff09;头删&#xff08;4&#xff09;尾删&#xff08;5&#xff09;单链表的查找&#xff08;6&#xff09;删除…

leetcode 879. Profitable Schemes(有利润的计划)

有几个工程&#xff0c;每个工程需要group[ i ]个人去做&#xff0c;做完了可以得到profit[ i ]的利润。 现有2个限制条件&#xff1a; 人数上限是n, 且参加了一个工程的人不能再参加其他工程。 利润下限minProfit, 至少要获得minProfit的利润。 问有多少种工程的选法&#xff…

Zuul源码解析(一)

说在前面 我们公司有一个线上服务报错通知群&#xff0c;经常报网关服务的一个 EOFException 异常。这个异常报出来好久了&#xff0c;如下图所示&#xff0c;艾特相关的人也不去处理&#xff0c;大概是不重要异常吧&#xff0c;反正看样子是不影响线上核心业务流程。 然后我上…

FreeRTOS学习笔记(一)——初识FreeRTOS

FreeRTOS官网&#xff1a;FreeRTOS - 适用于具有物联网扩展功能的嵌入式系统的市场领先 RTOS&#xff08;实时操作系统&#xff09; FreeRTOS源码下载&#xff1a;FreeRTOS Real Time Kernel (RTOS) - Browse /FreeRTOS at SourceForge.net 目录 0x01 FreeRTOS编程风格 一…

用CentOS服务器自己搭建部署个Discuz论坛网站,网站搭建教程

Linux系统CentOS服务器使用堡塔搭建论坛网站全套教程。服务器大本营&#xff0c;技术文章内容集合站发车啦&#xff01; 操作系统&#xff1a;Centos 7.6 网站程序&#xff1a;Discuz-X3.4 前言 首先&#xff0c;搭建一个网站需要准备&#xff1a;服务器、域名、网站程序。 …

PWM控制直流电机

一&#xff0c;TB6612电机驱动模块 直流电机属于大功率器件&#xff0c;GPIO无法直接驱动&#xff0c;需要电机驱动模块配合&#xff0c;才能驱动直流电机. TB6612可以驱动2个直流电机。由IN1&#xff0c;IN2控制电机旋转方向&#xff0c;由PWM控制电机旋转速度。 二&#xf…

基于Oracle VM VirtualBox的ubuntu的安装

基于Oracle VM VirtualBox的ubuntu的安装 感谢詹老师的帮助使我得以完成本次安装&#xff0c;以下为本次安装的一个小小的记录。 目录 基于Oracle VM VirtualBox的ubuntu的安装Oracle VM VirtualBox的下载与安装ubuntu的下载Oracle VM VirtualBox下安装ubuntu安装 ROS Melodi…

GitHub 开源神器 Bark模型,让文本转语音更简单

今天跟大家分享一个文本转语音的开源模型&#xff1a;Bark Bark 是由Suno创建的基于转换器的文本到音频模型。Bark 可以生成高度逼真的多语言语音以及其他音频 - 包括音乐、背景噪音和简单的音效。该模型还可以产生非语言交流&#xff0c;如大笑、叹息和哭泣。 该项目刚开源不…

二叉树OJ题(C++实现)

文章目录 1.二叉树创建字符串2. 二叉树的最近公共祖先3.二叉搜索树与双向链表4.从前序与中序遍历序列构造二叉树 1.二叉树创建字符串 二叉树的层序遍历 OJ连接 主要思路是借助一个队列&#xff0c;将每一层的数据以size统计&#xff0c;当size为0时说明该层数据已经输入完&…

Unity Physics2D 2d物理引擎游戏 笔记

2d 材质 里面可以设置 摩擦力 和 弹力 Simulated&#xff1a;是否在当前的物理环境中模拟&#xff0c;取消勾选该框类似于Disable Rigidbody&#xff0c;但使用这个参数更加高效&#xff0c;因为Disable会销毁内部产生的GameObject&#xff0c;而取消勾选Simulated只是禁用。…

详解C语言string.h中常用的14个库函数(四)

本篇博客会讲解最后4个函数&#xff0c;分别是memset, memcpy, memmove, memcmp。这4个函数开头都是mem&#xff0c;即memory&#xff08;内存&#xff09;的缩写。 memset void * memset ( void * ptr, int value, size_t num );memset可以用来设置内存中的值。该函数可以把从…

深度学习实战——循环神经网络(RNN、LSTM、GRU)

忆如完整项目/代码详见github&#xff1a;https://github.com/yiru1225&#xff08;转载标明出处 勿白嫖 star for projects thanks&#xff09; 目录 系列文章目录 一、实验综述 1.实验工具及内容 2.实验数据 3.实验目标 4.实验步骤 二、循环神经网络综述 1.循环神经…

【数据结构】第五章 树与二叉树

文章目录 知识体系5.1 树的基本概念5.1.1 树的定义5.1.2 基本术语5.1.3 树的性质 5.2 二叉树的概念5.2.1 二叉树的定义和主要特性5.2.2 二叉树的存储结构 5.3 二叉树的遍历和线索二叉树5.3.1 二叉树的遍历5.3.2 线索二叉树 5.4 树、森林5.4.1 树的存储结构5.4.2 树、森林与二叉…