Spring:了解@Import注解的三种用法
一、前言
在 Spring 框架中,@Import 注解用于导入配置类,使得你可以在一个配置类中引入另一个或多个配置类,从而实现配置的模块化。这对于组织大型应用程序的配置非常有用,因为它允许你将配置分散到多个类中,然后再将它们组合在一起。
本文将详细介绍@Import注解的三种方式,并通过示例演示它们的用法。通过对本文的阅读,读者将更好地理解@Import注解在Spring框架中的作用和应用。
二、 @Import 的三种用法
1. 导入普通的配置类
当你有多个配置类,并且想要将它们组合成一个更大的配置时,可以使用 @Import 来导入其他配置类。
代码示例:
// 配置类 A
@Configuration
public class MyConfigA { @Bean public MyServiceA myServiceA() { return new MyServiceA(); }
}
// 配置类 B,它导入了配置类 A
@Configuration
@Import(MyConfigA.class)
public class MyConfigB { @Bean public MyServiceB myServiceB(MyServiceA myServiceA) { return new MyServiceB(myServiceA); }
}
// 服务类 A
public class MyServiceA { // 业务处理
}
// 服务类 B
public class MyServiceB { private final MyServiceA myServiceA; public MyServiceB(MyServiceA myServiceA) { this.myServiceA = myServiceA; } // 代码逻辑
}
在上面例子中,MyConfigB 通过 @Import 导入了 MyConfigA,从而能够在 MyServiceB 中注入 MyService。
2. 导入实现了 ImportSelector 接口的类
当你想根据条件动态地导入配置类时,可以实现 ImportSelector 接口。
代码示例:
// ImportSelector 实现类
public class MyImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { // 这里简单起见,始终返回 MyConfigA.class 的名称 return new String[]{MyConfigA.class.getName()}; }
}
// 配置类 B,它导入了 MyImportSelector
@Configuration
@Import(MyImportSelector.class)
public class MyConfigB { // 代码逻辑
}
在这个例子中,MyConfigB 通过 @Import 导入了 MyImportSelector,而 MyImportSelector 会根据条件选择性地返回要导入的配置类名称。在这个简单的例子中,它始终返回 MyConfigA.class 的名称。
3. 导入实现了 ImportBeanDefinitionRegistrar 接口的类
当你想在导入配置时直接注册 BeanDefinition 到 Spring 容器中时,可以实现 ImportBeanDefinitionRegistrar 接口。
代码示例:
// ImportBeanDefinitionRegistrar 实现类
public class MyBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { RootBeanDefinition beanDefinition = new RootBeanDefinition(MyServiceA.class); registry.registerBeanDefinition("myServiceA", beanDefinition); }
}
// 配置类 B,它导入了 MyBeanDefinitionRegistrar
@Configuration
@Import(MyBeanDefinitionRegistrar.class)
public class MyConfigB { @Bean public MyServiceB myServiceB(MyServiceA myServiceA) { return new MyServiceB(myServiceA); }
}
在这个例子中,MyConfigB 通过 @Import 导入了 MyBeanDefinitionRegistrar,而 MyBeanDefinitionRegistrar 在 registerBeanDefinitions 方法中直接注册了一个 MyServiceA 的 BeanDefinition 到 Spring 容器中。这样,即使没有 MyConfigA 类,MyServiceB 也可以依赖注入 MyServiceA。
三、 项目实战
1. 准备一个实体类
package com.example.yddemo.test;public class User {private String name;private Integer age;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';}
}
2. 定义TestDefinitionRegistrar
package com.example.yddemo.test;import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;public class TestDefinitionRegistrar implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata annotationMetadata,BeanDefinitionRegistry beanDefinitionRegistry) {boolean beanDefinition = beanDefinitionRegistry.containsBeanDefinition("com.example.yddemo.test.User");if(beanDefinition){RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(User.class);beanDefinitionRegistry.registerBeanDefinition("user",rootBeanDefinition);}}}
3. 定义MySelector 选择器
package com.example.yddemo.test;import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;public class MySelector {public class SuperSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) {return new String[]{"com.example.yddemo.test.User"};}}}
4. 定义配置类
package com.example.yddemo.test;import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;@Configuration
@Import({User.class, MySelector.class,TestDefinitionRegistrar.class})
public class TestConfig {
}
5. 运行输出结果
package com.example.yddemo.test;import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class TestDemo {AnnotationConfigApplicationContext applicationContext =new AnnotationConfigApplicationContext(TestConfig.class);@Testpublic void testImport(){printBeans(applicationContext);User user = applicationContext.getBean(User.class);System.out.println("==================" + user);}private void printBeans(AnnotationConfigApplicationContext applicationContext){String[] definitionNames = applicationContext.getBeanDefinitionNames();for (String name : definitionNames) {System.out.println(name);}}
}

总结:
在本文中,我们介绍了Spring框架中的@Import注解及其三种方式。通过使用@Import注解,开发人员可以灵活地导入不同的配置类、依赖项以及自定义配置,从而更好地组织和管理应用程序的配置。通过示例演示,我们展示了@Import注解在不同场景下的用法,并强调了它在提高代码可维护性和可读性方面的重要性。通过阅读本文,读者可以更好地理解@Import注解在Spring框架中的作用和应用。
相关文章:
Spring:了解@Import注解的三种用法
一、前言 在 Spring 框架中,Import 注解用于导入配置类,使得你可以在一个配置类中引入另一个或多个配置类,从而实现配置的模块化。这对于组织大型应用程序的配置非常有用,因为它允许你将配置分散到多个类中,然后再将它…...
简要介绍三大脚本语言 Shell、Python 和 Lua
🍉 CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 脚本语言是一种用于自动化操作系统任务和应用程序功能的编程语言。它们通常用于编写小到中等规模的程序,以提高任务执行的速度和效率。在众多脚本语言中,Shell、Python 和 Lua 是…...
第 397 场 LeetCode 周赛题解
A 两个字符串的排列差 模拟:遍历 s s s 记录各字符出现的位置,然后遍历 t t t 计算排列差 class Solution {public:int findPermutationDifference(string s, string t) {int n s.size();vector<int> loc(26);for (int i 0; i < n; i)loc[s…...
文件存储解决方案-阿里云OSS
文章目录 1.菜单分级显示问题1.问题引出1.苹果灯,放到节能灯下面也就是id大于1272.查看菜单,并没有出现苹果灯3.放到灯具下面id42,就可以显示 2.问题分析和解决1.判断可能出现问题的位置2.找到递归返回树形菜单数据的位置3.这里出现问题的原因…...
基于Java的飞机大战游戏的设计与实现(论文 + 源码)
关于基于Java的飞机大战游戏.zip资源-CSDN文库https://download.csdn.net/download/JW_559/89313362 基于Java的飞机大战游戏的设计与实现 摘 要 现如今,随着智能手机的兴起与普及,加上4G(the 4th Generation mobile communication &#x…...
Vue路由开启步骤
1.在控制台输入命令 //控制台下载安装npm add vue-router3.6.5 2.在main.js下导入并注册组件 import Vue from vue import App from ./App.vue//控制台下载安装npm add vue-router3.6.5 //导入 import VueRouter from "vue-router";//注册 Vue.use(VueRouter) con…...
【碎片知识】2024_05_15
char int long float double运算的时候是从低转到高的,表达式的类型会自动提升或者转 换为参与表达式求值的最上级类型. 关于代码的说法正确的是( ) #include <stdio.h> int main() {int x -1;unsigned int y 2;if (x > y){printf…...
彩虹聚合DNS管理系统
聚合DNS管理系统可以实现在一个网站内管理多个平台的域名解析,目前已支持的域名平台有:阿里云、腾讯云、华为云、西部数码、CloudFlare。本系统支持多用户,每个用户可分配不同的域名解析权限;支持API接口,支持获取域名…...
服务网格 SolarMesh v1.13 重磅发布
SolarMesh是行云创新推出的流量治理平台,它基于Istio,为部署在K8s集群上的应用提供全面的流量治理能力。 在之前的版本中,SolarMesh提供的能力有:流量视图,流量控制策略批量配置,API级别的流量数据采集和展…...
三大平台直播视频下载保存方法
终于解决了视频号下载的问题,2024年5月15日亲测可用。 而且免费。 教程第二部分,有本地电脑无法下载的解决方案。 第一部分:使用教程(正常) 第1步:下载安装包 下载迅雷网盘搜索:大海福利合集…...
OpenAI GPT-4o - 介绍
本文翻译整理自: Hello GPT-4o https://openai.com/index/hello-gpt-4o/ 文章目录 一、关于 GPT-4o二、模型能力三、能力探索四、模型评估1、文本评价2、音频 ASR 性能3、音频翻译性能4、M3Exam 零样本结果5、视觉理解评估6、语言 tokenization 六、模型安全性和局限…...
QTreeView学习 branch 虚线设置
1、方法一: #include <QStyleFactory> ui.treeView->setStyle(QStyleFactory::create("windows")); 2、方法二: QString strtyle2 R"( QTreeView::branch:has-siblings:!adjoins-item { border-image: url(:/TreeViewDe…...
C++ 日志库 log4cpp 编译、压测及其范例代码 [全流程手工实践]
文章目录 一、 log4cpp官网二、下载三、编译1.目录结构如下2.configure 编译3.cmake 编译 四、测试五、压测源码及结果1.运行环境信息2.压测源码3.压测结果 文章内容:包含了对其linux上的完整使用流程,下载、编译、安装、测试用例尝试、以及一份自己写好…...
python数据处理与分析入门-pandas使用(4)
往期文章: pandas使用1pandas使用2pandas使用3 pandas使用技巧 创建一个DF对象 # 首先创建一个时间序列 dates pd.date_range(20180101, periods6) print(dates)# 创建DataFrame对象,指定index和columns标签 df pd.DataFrame(np.random.randn(6,4), …...
操作系统-单片机进程状态问题(三态模型问题)
例题:在单处理机计算机系统中有1台打印机、1台扫描仪,系统采用先来先服务调度算法。假设系统中有进程P1、P2、P3、P4,其中P1为运行状态,P2为就绪状态,P3等待打印机,P4等待扫描仪。此时,若P1释放…...
Linux文件:重定向底层实现原理(输入重定向、输出重定向、追加重定向)
Linux文件:重定向底层实现原理(输入重定向、输出重定向、追加重定向) 前言一、文件描述符fd的分配规则二、输出重定向(>)三、输出重定向底层实现原理四、追加重定向(>>)五、输入重定向…...
波搜索算法(WSA)-2024年SCI新算法-公式原理详解与性能测评 Matlab代码免费获取
声明:文章是从本人公众号中复制而来,因此,想最新最快了解各类智能优化算法及其改进的朋友,可关注我的公众号:强盛机器学习,不定期会有很多免费代码分享~ 目录 原理简介 一、初始化阶段 二、全…...
洛谷P1364 医院设置
P1364 医院设置 题目描述 设有一棵二叉树,如图: 其中,圈中的数字表示结点中居民的人口。圈边上数字表示结点编号,现在要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定,…...
哈希表的理解和实现
目录 1. 哈希的概念 (是什么) 2. 实现哈希的两种方式 (哈希函数) 2.1. 直接定址法 2.2. 除留余数法 2.2.1. 哈希冲突 3. 补充知识 3.1. 负载因子 3.2. 线性探测和二次探测 4. 闭散列实现哈希表 (开放定址法) 4.1. 开放定址法的实现框架 4.2. Xq::hash_table::insert…...
分治算法(Divide-and-Conquer Algorithm)
分治算法(Divide-and-Conquer Algorithm)是一种重要的计算机科学和数学领域的通用问题解决策略。其基本思想是将一个复杂的大规模问题分割成若干个规模较小、结构与原问题相似但相对简单的子问题来处理。这些子问题相互独立,分别求解后再通过…...
[通俗易懂]从“生产者-消费者”模型秒懂Java泛型PECS原则(别再死记硬背了)
1. 从超市购物理解PECS原则 想象你正在超市采购水果。水果区有各种水果篮:有的专放苹果,有的专放香蕉,还有个"混合水果区"放各种水果。这时候你会发现两个有趣的现象: 从水果区取水果:你可以从任何水果篮里安…...
【技术解析】从点测量到全场感知:DIC三维应变测量如何革新传统应变片测试范式
1. 从点到面的技术革命:为什么我们需要全场应变测量? 记得我第一次接触材料力学测试时,导师让我用传统应变片测量一块铝合金板的拉伸变形。我花了整整三天时间,在试样上贴了二十多个应变片,结果数据还是支离破碎。那时…...
计算机生成全息技术参数敏感性分析与优化策略
1. 计算机生成全息技术中的参数敏感性研究在光学工程领域,计算机生成全息(Computer-Generated Holography, CGH)技术正经历着从传统迭代算法到神经网络方法的范式转变。这项技术的核心挑战在于如何高效准确地重建目标光场——这本质上是一个相…...
【软考高级架构】论文范文20——论软件设计方法及其应用
论软件设计方法及其应用 摘要 软件设计是将需求分析结果转换为软件体系结构和内部实现细节的关键活动,设计方法的选择直接影响系统的可维护性、可扩展性和开发效率。结构化设计、面向对象设计、数据驱动设计等经典方法各有侧重,在不同场景下展现出独特的优势。本文以笔者主…...
利用Taotoken的Token Plan套餐为团队项目节省大模型调用成本
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 利用Taotoken的Token Plan套餐为团队项目节省大模型调用成本 对于中小型技术团队而言,在项目开发中引入大模型能力已成…...
RK3588/RK1820嵌入式AI模型选型与部署实战:9大模型场景化应用指南
1. 项目概述:嵌入式AI模型部署的十字路口作为一名在嵌入式AI领域摸爬滚打了十多年的老兵,我见过太多项目在模型部署这个环节上栽跟头。大家手里可能都握着RK3588、RK182X这类性能强悍的瑞芯微平台,硬件算力摆在那里,但真要把一个A…...
ArduPilot硬件抽象层(HAL)详解:如何让你的代码跑在不同的飞控板上(以STM32为例)
ArduPilot硬件抽象层深度解析:从STM32到多平台移植实战指南 引言:为什么HAL是飞控开发的核心枢纽 在无人机飞控开发领域,硬件平台的多样性一直是开发者面临的首要挑战。不同厂商的MCU架构、外设接口和操作系统差异,往往导致代码…...
Bootstrap5 侧边栏导航
Bootstrap5 侧边栏导航 随着Web技术的发展,用户界面(UI)设计越来越受到重视。Bootstrap作为一个流行的前端框架,它为开发者提供了丰富的组件和工具,以快速构建响应式、移动优先的网站和应用程序。在Bootstrap 5中,侧边栏导航是一个重要的组件,它可以帮助用户在网站或应…...
2025终极免费IDM激活方案:一键永久解锁下载管理神器
2025终极免费IDM激活方案:一键永久解锁下载管理神器 【免费下载链接】IDM-Activation-Script IDM Activation & Trail Reset Script 项目地址: https://gitcode.com/gh_mirrors/id/IDM-Activation-Script 还在为Internet Download Manager(ID…...
AMD Ryzen SMU Debug Tool完全指南:揭秘硬件级调试的三大实战场景
AMD Ryzen SMU Debug Tool完全指南:揭秘硬件级调试的三大实战场景 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址:…...
