springboot自动装配原理,手写一个starter。

文章目录

  • springboot自动装配原理
  • 手写starter
  • 手写starter总结:

springboot自动装配原理

口述:

  1. springboot自动装配的话它其实就是只需要我们添加一个starter起步依赖,它就能完成这个依赖组件相关Bean的自动注入,其实就是自动的将我们所需要的Bean装配到IoC容器中,比如说我们用redis的话,我们只需要将redis的一个data-redis的starter起步依赖引入,并且在配置文件中去指出ip端口,那我们在程序中就可以用autowired注入redisTemplate,就可以用了,其实这个redisTemplate就已经存在在IOC容器中了,我们用直接取就可以了,其实这个就是自动装配了我们redis所需要的bean了。
  2. 它其实是因为我们在启动类上面的springbootapplication注解里面,包含着@enableautoconfiguration注解,它表示我们开启了自动装配,其实在这个@enableautoconfiguration注解里面有@import这个注解,@import的话我们常用的就是将配置类传入进去,这个配置类基本就是用@configuration注解和@bean注解来定义的,import就可以将bean注入到ioc容器中,但这里的import它传入的是一个ImportSelector的实现类,@AutoConfigurationImportSelector,它实现了ImportSelector,重写了selectImports这个方法,这个方法主要有两个作用,第一个就是它会去筛选我们的配置类,就是只有满足条件的bean才能进行装配,它其实就是通过METE-INF/spring-autoconfigure-metadata.properties这个配置文件中去筛选的,这个配置文件的话其实就相当于一个个@conditional这个注解,就是一些条件的判断,当满足什么什么条件时加载这个bean,其实就是一个过滤筛选的作用。
  3. 然后这个selectimports方法的第二个作用就是收集符合条件的配置类完成自动装配,就是通过autoConfigurationEntry.getConfigurations()这个方法实现的,其实在实际执行过程中的话它是同过ConfigurationClass的这个增强器PostProcessor中的BeanDefinitions这个方法来扫描注册配置类的Bean的,最终的话也还是会调用autoConfigurationEntry这个方法获得需要自动配置的配置类的。
  4. 其实这个autoConfigurationEntry,这个配置类的收集方法它里面的话也定义了很多的方法,比如getAttributes获得这个@EnableAutoConfiguration注解中的属性,还有一些去重啊就是去除重复类啊、最核心的话是这个canditate这个方法,就是getCandidateConfigurations这个方法,它会获得所有的自动装配的配置类,其实也就是METE-INF/spring.factories这个文件中的value,其实这个candidate这个方法的话也是用到了spring中的加载方式,就是SpringFactoriesLoader,它就会从spring.factories这个文件中找到对应key的value,比如说我们现在自动装配的话那key就是EnableAutoConfiguration,然后的话取到这个接口的对应实现类,实现类的话也是很多的,然后candidate拿到这些实现类的话就会经过去重啊、筛选啊等等选出我们要的实现类。
  5. 就比如说redis的自动配置类,就是RedisAutoConfiguration这个类,这个类上面的话是有@Configuration表示它是一个配置类,然后@ConditionalOnClass()这个注解它其实会判断我们的这个redisTemplate是否在类路径下,因为我们引入了spring-boot-starter-data-redis这个起步依赖,那它所对应的类比如redistemplate也会存在于类路径下,这个时候就会吧redistemplate这个bean注入到ioc容器中,其实这个的话也就是springboot我们引入什么依赖才会将它所对应的bean注入到ioc容器中,没有用到的依赖就不会注入,这个的话就是springboot自动装配的原理。

手写starter

核心三点:

  1. 相关组件的jar包依赖
  2. 自动完成bean的装配
  3. 加载application.properties文件中的属性配置

要求:写一个组件来实现redisTemplate的自动装配
步骤:
1 创建一个工程
5. 添加jar包依赖

		<dependency><groupId>org.redission</groupId><artifactId>redission</artifactId><version>3.11.1</version></dependency>

3.定义属性类,@ConfigurationProperties这个注解作用就是吧当前类中的属性和我们配置文件中的配置进行绑定,并且前缀是gp.redisson

package cn.itcast.demo;import io.netty.util.Timeout;
import org.springframework.boot.context.properties.ConfigurationProperties;@ConfigurationProperties(prefix = "gp.redission")
public class RedissonProperties {private String host = "localhost";private String password;private int port = 6379;private int timeout;public void setHost(String host) {this.host = host;}public void setPassword(String password) {this.password = password;}public void setPort(int port) {this.port = port;}public void setTimeout(int timeout) {this.timeout = timeout;}public void setSsl(boolean ssl) {this.ssl = ssl;}public String getHost() {return host;}public String getPassword() {return password;}public int getPort() {return port;}public int getTimeout() {return timeout;}public boolean isSsl() {return ssl;}private boolean ssl;
}

4.定义需要自动装配的配置类,吧RedissionClient装配到ioc容器。
在这里插入图片描述
注意:这里需要说明一下,我们引入的是redission依赖,那我们想要用redisTemplate,什么时候将其注入到bean呢?那就是@ConditionalOnClass(redission.class)在类路径下存在的情况下注入,其实它就是个判断条件,我们不能说吧我们没有引入的依赖注入到ioc容器吧,那肯定是引入了什么依赖吧对应的依赖的bean注入到ioc容器中,这里的话redission就充当了条件,我们用redission当作条件指明现在是引入了redission依赖了,我们要将操作redis的bean注入ioc,那如果不判断的话,我们pom文件引入的依赖怎么用呢?或者说我们怎么知道该注入哪些bean呢?其实就是pom文件我们引入的依赖所引起来的,这其实就是springboot较spring做的改进,spring我们注入bean需要手动加配置类加bean才能注入,那如果注入的特别多是不是很繁琐呢?springboot自动装配是实现了用什么依赖我注依赖所对应的bean,不需要我们手动注入,非常大的改进。

5.在resource下创建METE-INF/spring.factories文件,使得springboot程序可以扫描到该文件完成自动装配,key和value对应如下:
在这里插入图片描述
6.使用:添加starter依赖、设置属性配置,然后autowired就可以注入了
在这里插入图片描述

手写starter总结:

starter的作用就是引入了相应的jar包依赖,自动实现与该依赖有关的bean的注入,并且将我们在resource下配置文件中配置的数据和引入的这个依赖的属性类中的属性进行绑定。

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

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

相关文章

使用Python进行健身手表数据分析

健身手表(Fitness Watch)数据分析涉及分析健身可穿戴设备或智能手表收集的数据&#xff0c;以深入了解用户的健康和活动模式。这些设备可以跟踪所走的步数、消耗的能量、步行速度等指标。本文将带您完成使用Python进行Fitness Watch数据分析的任务。 Fitness Watch数据分析是健…

S7-1200/1500增量式PID(输出归一化、支持PWM输出)

离散增量式PID算法公式请查看下面文章链接: 三菱PLC增量式PID算法FB(带死区设置和外部复位控制)_用三菱plc自己编写pid算法_RXXW_Dor的博客-CSDN博客关于PID废话不多说,各种位置式增量式资料和公式网上也非常多。PID从提出和发展目前已经一个世纪过去了,还在不断研究创新,…

Java多线程(Thread)详解之启动与中断

在我的前一篇博客中直接介绍了Thread的”五种“打开方式&#xff1a;Thread的”五种“打开方式https://blog.csdn.net/qq_45875349/article/details/132644717?spm1001.2014.3001.5501 但是还没有详细的对Thread类进行说明&#xff0c;这篇博客主要对Thread类进行介绍&#x…

全局指令和局部指令

自定义v-load <template><div class"main"><div class"box" v-loading"isLoading"><ul><li v-for"item in list" :key"item.id" class"news"><div class"left">…

【网络编程】TCP/IP协议(互联网的基石)

(꒪ꇴ꒪ )&#xff0c;Hello我是祐言QAQ我的博客主页&#xff1a;C/C语言&#xff0c;数据结构&#xff0c;Linux基础&#xff0c;ARM开发板&#xff0c;网络编程等领域UP&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff0c;让我们成为一个强大的攻城狮&#xff0…

实时操作系统Freertos开坑学习笔记:(四):临界段保护、列表与列表项

前言 废话不多说&#xff0c;直接看主要要探究的问题&#xff1a; 一、临界段代码保护 1.什么是临界段&#xff1f; 图里面说&#xff0c;临界区的代码是不能被打断的&#xff0c;它运行时不能被中断打断&#xff0c;也不能由于非阻塞任务延时而切换到其他任务去。 比如说…

bash: cmake: command not found...+++++++lsb_release: command not found

一 .bash: cmake: command not found… centos中安装那个cmake。 1、问题 [rootPC3 home]# cmake bash: cmake: command not found... Similar command is: make当前系统&#xff1a; [rootPC3 home]# lsb_release -a LSB Version: :core-4.1-amd64:core-4.1-noarch:cxx…

蝶形运算法

蝶形运算法是一种基于FFT&#xff08;Fast Fourier Transform&#xff09;算法的计算方法&#xff0c;其基本思想是将长度为N的DFT分解成若干个长度为N/2的DFT计算&#xff0c;并通过不断的合并操作得到最终的结果。该算法也称为“蝴蝶算法”&#xff0c;因为它的计算过程中需要…

[Android 四大组件] --- Activity

1 Activity是什么 ​​Activity​​是一个Android的应用组件&#xff0c;它提供屏幕进行交互。每个Activity都会获得一个用于绘制其用户界面的窗口&#xff0c;窗口可以充满哦屏幕也可以小于屏幕并浮动在其他窗口之上。 一个应用通常是由多个彼此松散联系的Activity组成&…

vue3学习笔记

语句直接写在<script setup></script>内 1.父组件向子组件传值 子组件&#xff08;名字cs.vue&#xff09;&#xff1a; <template><h1 >{{ msg }}</h1> </template><script setup> defineProps({msg: String }) </script>父…

LeetCode--HOT100题(47)

目录 题目描述&#xff1a;105. 从前序与中序遍历序列构造二叉树&#xff08;中等&#xff09;题目接口解题思路代码 PS: 题目描述&#xff1a;105. 从前序与中序遍历序列构造二叉树&#xff08;中等&#xff09; 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preo…

【AI测试】python文字图像识别tesseract

[AI测试]python文字图像识别tesseract github官网&#xff1a;https://github.com/tesseract-ocr/tesseract python版本&#xff1a;https://github.com/madmaze/pytesseract OCR&#xff0c;即Optical Character Recognition&#xff0c;光学字符识别&#xff0c;是指通过扫…

工程制造领域:企业IT架构

一、IT组织规划架构图 1.1 IT服务保证梯队与指导思想 二、整体业务规划架构图 三、数据化项目规划架构图 四、应用系统集成架构图

CSS Flex布局

前言 Flex布局&#xff08;弹性盒子布局&#xff09; 是一种用于在容器中进行灵活和自适应布局的CSS布局模型。通过使用Flex布局&#xff0c;可以更方便地实现各种不同尺寸和比例的布局&#xff0c;使元素在容器内自动调整空间分配。 目录 容器属性 &#x1f341;display属性 &…

数据结构与算法复杂度介绍

目录 一、基本概念 二、时间复杂度 【2.1】时间复杂度概念 【2.2】大O的渐进表示法 【2.3】举例时间复杂度计算 三、空间复杂度 一、基本概念 数据结构&#xff1a;相互之间存在一种或者多种特定关系的数据元素的集合。在逻辑上可以分为线性结构&#xff0c;散列结构、树…

单片机电子元器件-按键

电子元器件 按键上有 四个引脚 1 2 、 3 4 按下之后 导通 1 3 、 2 4 初始导通 通常按键开关为机械弹性开关&#xff0c;开关在闭合不会马上稳定的接通&#xff0c;会有一连串的抖动 抖动时间的长短有机械特性来决定的&#xff0c;一般为5ms 到10 ms 。 消抖的分类 硬件消…

【大数据Hive】hive 加载数据常用方案使用详解

目录 一、前言 二、load 命令使用 2.1 load 概述 2.1.1 load 语法规则 2.1.2 load语法规则重要参数说明 2.2 load 数据加载操作演示 2.2.1 前置准备 2.2.2 加载本地数据 2.2.3 HDFS加载数据 2.2.4 从HDFS加载数据到分区表中并指定分区 2.3 hive3.0 load 命令新特性 …

vue项目配置MongoDB的增删改查操作

在Vue中配置MongoDB的增删改查操作&#xff0c;需要先安装mongoose模块来连接MongoDB数据库。 1. 在Vue项目的根目录中&#xff0c;使用命令行安装mongoose模块&#xff1a; npm install mongoose --save 2. 找到启动node的app.js文件&#xff08;我这里是在server文件中&…

Java开发之Redis(面试篇 持续更新)

文章目录 前言一、redis使用场景1. 知识分布2. 缓存穿透① 问题引入② 举例说明③ 解决方案④ 实战面试 3. 缓存击穿① 问题引入② 举例说明③ 解决方案④ 实战面试 4. 缓存雪崩① 问题引入② 举例说明③ 解决方案④ 实战面试 5. 缓存-双写一致性① 问题引入② 举例说明③ 解决…

Linux执行命令

命令格式 主命令 选项 参数&#xff08;操作对象&#xff09;例如&#xff1a; 修改主机名 hostname set-hostname 新名称显示/目录下的文件的详细信息 ls -l /命令 内置命令&#xff08;builtin&#xff09;&#xff1a;shell程序自带的命令。 外部命令&#xff1a;有独立…