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

Spring-ImportSelector接口功能介绍

ImportSelector接口是至spring中导入内部类或者外部类的核心接口,只需要其定义的方法内返回需要创建bean的class字符串就好了,比如:当我们引入一个外部share包,我们拿到里面的Class返回出去,就能得到这个bean,是多么神奇的事情,前提是这个类不是接口哦。

ImportSelector往往结合@Import注解一起使用,可以参考我的这篇文章@Import注解介绍

public interface ImportSelector {//返回类的字符串数组,也就是要创建的bean的className,比如userService.class.getName()//被创建的bean是在其他bean(@Component、@Service等注解修饰的Bean)创建之前创建的String[] selectImports(AnnotationMetadata importingClassMetadata);
}

二、使用案例

通过返回Class的字符串来创建bean

//定义一个业务类
public class UserServiceTest {public String getUserName(){return "测试";}
}//实现ImportSelector接口
public class MyImportSelect implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {//返回要注册到Spring容器的Class集合return new String[]{UserServiceTest.class.getName()};}
}//配置类
@Configuration
@Import(MyImportSelect.class) //导入我们实现ImportSelector的类。
public class AppConfigClassTest {
}

测试

public class MainTest {public static void main(String[] args) {AnnotationConfigApplicationContext AnnotationConfigApplicationContext = new AnnotationConfigApplicationContext(AppConfigClassTest.class);//这里我们不能通过“userServiceTest”来获取bean,因为这个bean的name不是userServiceTest,而是userServiceTest.getClass().getName()//因为bean的别名成功器,只是针对像注解@Service等注解,会生成一个首字母小写的BeanNameUserServiceTest userServiceTest = AnnotationConfigApplicationContext.getBean(UserServiceTest.class);System.out.println(((UserServiceTest)userServiceTest).getUserName());}
}

下面说下源码是怎么实现的,可以跳转到@Import注解介绍

//这里就直接跳到ConfigurationClassPostProcessor处理@Import注解的逻辑上
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass, Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter, boolean checkForCircularImports) {//如果importCandidates为空直接return,为什么会有这个,因为下面代码可能会递归调用processImports,就比如Import一个类,这个类也带了@Import注解,那就会在调用一次processImports方法if (importCandidates.isEmpty()) {return;}for (SourceClass candidate : importCandidates) {if (candidate.isAssignable(ImportSelector.class)) {//1、import的类,实现了ImportSelector接口Class<?> candidateClass = candidate.loadClass();//利用反射Class实例化对象,这个对象不是代理对象不要搞混了。ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class,this.environment, this.resourceLoader, this.registry);Predicate<String> selectorFilter = selector.getExclusionFilter();if (selectorFilter != null) {exclusionFilter = exclusionFilter.or(selectorFilter);}if (selector instanceof DeferredImportSelector) {this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);} else {//调用ImportSelector接口里面的selectImports方法,拿到返回值Class集合。在通过递归的方式嗲用processImports挨个解析每一个ClassString[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());//转成SourceClass集合Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);//再次调用processImports方法processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);}} else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {。。。。。。} else {//3、ImportSelector和ImportBeanDefinitionRegistrar都没有实现this.importStack.registerImport(currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());//进一步解析其他注解,比如@Component @Import等最后会把configClass注册到Spring容器中。processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);}}
}

看下instantiateClass方法做了什么

//创建实例对象
static <T> T instantiateClass(Class<?> clazz, Class<T> assignableTo, Environment environment, ResourceLoader resourceLoader, BeanDefinitionRegistry registry) {ClassLoader classLoader = (registry instanceof ConfigurableBeanFactory ? ((ConfigurableBeanFactory) registry).getBeanClassLoader() : resourceLoader.getClassLoader());T instance = (T) createInstance(clazz, environment, resourceLoader, registry, classLoader);ParserStrategyUtils.invokeAwareMethods(instance, environment, resourceLoader, registry, classLoader);return instance;
}//调用createInstance方法创建实例对象
private static Object createInstance(Class<?> clazz, Environment environment, ResourceLoader resourceLoader, BeanDefinitionRegistry registry, @Nullable ClassLoader classLoader) {Constructor<?>[] constructors = clazz.getDeclaredConstructors();。。。。。。。return BeanUtils.instantiateClass(clazz);//通过Bean的工具类生成实例对象
}

相关文章:

Spring-ImportSelector接口功能介绍

ImportSelector接口是至spring中导入内部类或者外部类的核心接口&#xff0c;只需要其定义的方法内返回需要创建bean的class字符串就好了&#xff0c;比如&#xff1a;当我们引入一个外部share包&#xff0c;我们拿到里面的Class返回出去&#xff0c;就能得到这个bean,是多么神…...

YOLOv5如何训练自己的数据集

文章目录 前言1、数据标注说明2、定义自己模型文件3、训练模型4、参考文献 前言 本文主要介绍如何利用YOLOv5训练自己的数据集 1、数据标注说明 以生活垃圾数据集为例子 生活垃圾数据集&#xff08;YOLO版&#xff09;点击这里直接下载本文生活垃圾数据集 生活垃圾数据集组成&…...

李航老师《统计学习方法》第1章阅读笔记

1.1 统计学习 统计学习的特点 统计学习&#xff1a;计算机基于数据构建概率统计模型并运用模型对数据进行预测与分析 现在人们提及机器学习时&#xff0c;往往指统计机器学习&#xff0c;所以可以认为本书介绍的是机器学习方法 统计学习的对象 统计学习研究的对象是数据(data)…...

基于微信小程序的背单词学习激励系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言用户微信端的主要功能有&#xff1a;管理员的主要功能有&#xff1a;具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉…...

VScode调试复杂C/C++项目

以前都是用的VScode调试c/cpp的单个文件的编译和执行, 但是一遇到大型项目一般就用gdb了, gdb的调试效率和VScode差距还是比较大的, 但最近发现VScode其实也能调试复杂的cpp项目, 所以记录一下. 首先明确一下几点: 首先cpp文件需要经过编译, 生成可执行文件, 然后通过运行/调…...

【Hash表】字母异位词分组-力扣 49 题

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学…...

展示日志log4.properties

log4.properties 1.log4.properties 此时文件主要用于展示日志的输出的级别的信息。 # Set root category priority to INFO and its only appender to CONSOLE. #log4j.rootCategoryINFO, CONSOLE debug info warn error fatal log4j.rootCategoryinfo, CONSO…...

基于PLE结合卡尔曼滤波的RSSI定位算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022a 3.部分核心程序 ............................................................... for Num_xb Num_xb2Num_…...

uniapp项目实践总结(十九)版本更新和热更新实现方法

导语:当一个 APP 应用开发完成以后,就要上架应用商店,但有时候修改一些小问题或者推出一些活动,又不想频繁地提交应用商店审核,那么就可以使用应用内更新功能来进行应用的版本升级更新或热更新,下面就介绍一下实现的方法。 目录 准备工作原理分析实战演练案例展示准备工作…...

一起学数据结构(8)——二叉树中堆的代码实现

在上篇文章中提到&#xff0c;提到了二叉树中一种特殊的结构——完全二叉树。对于完全二叉树&#xff0c;在存储时&#xff0c;适合使用顺序存储。对于非完全二叉树&#xff0c;适合用链式存储。本文将给出完全二叉树的顺序结构以及相关的代码实现&#xff1a; 1. 二叉树的结构…...

Linux环境变量配置说明(配置jdk为例-摘录自尚硅谷技术文档)

配置环境变量的不同方法 Linux的环境变量可在多个文件中配置,如/etc/profile&#xff0c;/etc/profile.d/.sh&#xff0c;~/.bashrc&#xff0c;~/.bash_profile等&#xff0c;下面说明上述几个文件之间的关系和区别。 bash的运行模式可分为login shell和non-login shell。 例…...

idea常用插件笔记

文章目录 Free Mybatis Toollombok插件idea插件导出导入 idea提供了很多好用的插件&#xff0c;之前都装了的&#xff0c;但是换了下电脑&#xff0c;什么都没了&#xff0c;所以记录下方便以后用。 Free Mybatis Tool mybatis跳转插件&#xff0c;再也不用费力的找xml了。 l…...

搜索二叉树【C++】

文章目录 二叉搜索树二叉搜索树的模拟实现构造函数拷贝构造函数赋值运算符重载函数析构函数Insert循环递归 Erase循环递归 Find循环递归 二叉搜索树的应用K模型KV模型 完整代码普通版本递归版本 二叉搜索树 二叉搜索树又称为二叉排序树&#xff0c;它或者是一棵空树&#xff0…...

华为云云耀云服务器L实例评测|认识redis未授权访问漏洞 漏洞的部分复现 设置连接密码 redis其他命令学习

前言 最近华为云云耀云服务器L实例上新&#xff0c;也搞了一台来玩&#xff0c;期间遇到过MySQL数据库被攻击的情况&#xff0c;数据丢失&#xff0c;还好我有几份备份&#xff0c;没有造成太大的损失。昨天收到华为云的邮箱提醒&#xff0c;我的redis数据库没有设置密码&…...

快速安装NGINX

快速安装NGINX #安装依赖包 yum -y install gcc pcre pcre-devel zlib zlib-devel openssl openssl-devel#下载NGINX curl -O https://nginx.org/download/nginx-1.21.6.tar.gz#解压NGINX tar -zxvf nginx-1.21.6.tar.gz cd nginx-1.21.6.tar.gz#配置 ./configure --prefix/…...

一台电脑远程内网的另外一台电脑,禁止远程的电脑连接外网,只允许内网连接

一台电脑远程内网的另外一台电脑&#xff0c;禁止远程的电脑连接外网&#xff0c;只允许内网连接 1.找到右下角网卡图标&#xff0c;右键图标选择“打开网络和共享中心”。 3、点击“更改适配器设置”。 4、右键正在使用的网卡“本地连接”打开属性 5、找到“internet协…...

山西电力市场日前价格预测【2023-09-24】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-09-24&#xff09;山西电力市场全天平均日前电价为496.09元/MWh。其中&#xff0c;最高日前电价为705.54元/MWh&#xff0c;预计出现在14: 30。最低日前电价为333.70元/MWh&#xff0c;预计…...

MQ---第二篇

系列文章目录 文章目录 系列文章目录一、RabbitMQ事务消息二、RabbitMQ死信队列、延时队列一、RabbitMQ事务消息 通过对信道的设置实现 channel.txSelect();通知服务器开启事务模式;服务端会返回Tx.Select-Okchannel.basicPublish;发送消息,可以是多条,可以是消费消息提交…...

C++ 创建文件并写入内容

文章目录 1.问题2.filesystem3.示例参考文献 1.问题 C 如何向指定路径的文件写入内容呢&#xff1f; 这里有几点要求&#xff1a; 如果目录不存在需要自动创建。如果文件不存在需要自动创建。以覆盖的方式写入内容。 2.filesystem C17 带来了一个新的库&#xff1a;filesy…...

微信小程序rich-text里面写多行溢出显示省略号在ios中不显示的问题

问题&#xff1a;微信小程序rich-text里面写多行溢出显示省略号在ios中不显示的问题 解决方法&#xff1a;需要给一个默认的div标签&#xff0c;在div写行内样式 overflow : hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-o…...

R语言中的loess函数:从原理到实战时序数据分析

1. 理解loess回归&#xff1a;从数学原理到生活场景 第一次接触loess函数时&#xff0c;我盯着金融数据里那些弯弯曲曲的折线图发愁——传统的线性回归画出来的直线根本抓不住股价的波动规律。这就像用直尺画蒙娜丽莎的微笑&#xff0c;技术没错&#xff0c;但完全不对味。loes…...

SpringBoot+Vue 学生评奖评优管理系统管理平台源码【适合毕设/课设/学习】Java+MySQL

摘要 随着教育信息化的快速发展&#xff0c;学生评奖评优管理作为高校学生工作的重要组成部分&#xff0c;传统的手工操作模式已难以满足高效、公正、透明的需求。学生评奖评优管理系统通过数字化手段实现评奖流程的自动化&#xff0c;能够有效减少人为干预&#xff0c;提高评…...

全面掌握MelonLoader:Unity游戏Mod加载器的终极指南

全面掌握MelonLoader&#xff1a;Unity游戏Mod加载器的终极指南 【免费下载链接】MelonLoader The Worlds First Universal Mod Loader for Unity Games compatible with both Il2Cpp and Mono 项目地址: https://gitcode.com/gh_mirrors/me/MelonLoader 你是否曾经为Un…...

告别面包板!用Multisim仿真74LS192+数码管,快速验证你的抢答器电路设计

用Multisim高效仿真数字电路&#xff1a;从74LS192计数器到抢答器实战 在电子设计领域&#xff0c;仿真技术已经成为硬件开发不可或缺的一环。想象一下这样的场景&#xff1a;你脑海中浮现出一个智能抢答器的设计方案&#xff0c;但不确定计数器与编码器的配合是否合理&#xf…...

万物识别-中文镜像多场景落地:已接入12家中小制造企业视觉质检系统

万物识别-中文镜像多场景落地&#xff1a;已接入12家中小制造企业视觉质检系统 1. 万物识别技术概述 万物识别技术正在改变传统制造业的质检方式。这项技术基于先进的深度学习算法&#xff0c;能够自动识别图像中的物体并给出准确标签。对于中小制造企业来说&#xff0c;这意…...

【nginx】深入解析net::ERR_CONTENT_LENGTH_MISMATCH 200:权限配置与日志排查实战

1. 错误现象与初步诊断 当你用浏览器访问Nginx托管的网站时&#xff0c;突然看到控制台报错net::ERR_CONTENT_LENGTH_MISMATCH 200&#xff0c;但页面居然还能正常显示部分内容&#xff0c;这种情况是不是很诡异&#xff1f;我第一次遇到时也是一头雾水。这个错误表面看是内容长…...

OpenClaw新手避坑指南:Qwen3.5-9B对接常见问题解决方案

OpenClaw新手避坑指南&#xff1a;Qwen3.5-9B对接常见问题解决方案 1. 为什么需要这份指南 上周我在本地部署OpenClaw对接Qwen3.5-9B模型时&#xff0c;连续踩了五个坑。从安装报错到模型连接超时&#xff0c;每个问题都消耗了我至少两小时的排查时间。这种经历让我意识到&am…...

03-Open code MCP 与工具调用

03-MCP 与工具调用 掌握 OpenCode 中 MCP&#xff08;Model Context Protocol&#xff09;服务器的配置和使用&#xff0c;扩展 AI 的工具能力。 一、MCP 概述 1.1 什么是 MCP MCP&#xff08;Model Context Protocol&#xff09;是一种标准化协议&#xff0c;允许 AI 模型与…...

CANopen网络管理NMT避坑指南:从心跳报文0x7F看懂节点状态与PDO失效原因

CANopen网络管理NMT实战诊断&#xff1a;从心跳报文解码到PDO失效精准定位 当你在调试一个由二十多个CANopen节点组成的自动化产线时&#xff0c;突然发现3号工位的传感器数据停止更新——这种场景对工业现场工程师来说再熟悉不过。更棘手的是&#xff0c;CAN分析仪上不断刷新的…...

rnnoise预计算表的终极指南:如何加速音频降噪性能

rnnoise预计算表的终极指南&#xff1a;如何加速音频降噪性能 【免费下载链接】rnnoise Recurrent neural network for audio noise reduction 项目地址: https://gitcode.com/gh_mirrors/rn/rnnoise RNNoise是一个基于循环神经网络的实时音频降噪库&#xff0c;它通过预…...