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;
    }

    @Override
    public 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 {

    @Override
    public 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 {
        @Override
        public 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);

    @Test
    public 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框架中的作用和应用。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

RAW转换和图像编辑工具:Capture One 23 Pro (win/mac)中文专业版

Capture One 23是一款功能强大的桌面版照片编辑软件,由丹麦PHASE ONE飞思数码公司开发。 以下是该软件的一些主要特点: 强大的RAW处理功能:Capture One 23支持多种品牌的相机和镜头,提供了丰富的RAW处理工具,包括曝光、…

RALL-E: Robust Codec Language Modeling with Chain-of-Thought Prompting for TTS

demo pageDetai Xin, tanxu微软 & 东大 & 浙大 abstract 使用CoT的思路,和Valle的框架,先实现LLM预测音素级别pitch/duration,然后预测speech token。 methods Prosody tokens as chain-of-thought prompts 和Valle一…

【JavaEE】Servlet

文章目录 一、Servlet 是什么二、如何创建Servlet程序1、创建项目2、引入依赖3、创建目录4、编写代码5、打包程序6、部署程序7、验证程序 一、Servlet 是什么 二、如何创建Servlet程序 1、创建项目 2、引入依赖 Maven 项目创建完后,会自动生成一个 pom.xml 的文…

独家|暴雨推出基于国产X86芯片的四路服务器

伴随着智慧计算时代的到来和企业数字化转型的深入,人工智能、大数据、虚拟化等创新技术在应用普及的过程中,也在不断地细分和深化,使得企业的业务系统日趋复杂,数据量、数据类型更加庞大,对计算平台的性能要求“水涨船…

Google I/O 2024:探索未来AI技术的无限可能

近日,Google I/O 2024大会圆满落幕,带给我们一场关于人工智能的盛宴。在这场大会上,Google推出了一系列令人激动的AI新功能和工具,让我们得以一窥未来的科技发展。今天,就让我来为大家总结一下这些亮点吧! …

一键修复所有dll缺失,教大家解决丢失的dll文件

修复所有DLL(动态链接库)文件缺失的问题通常不可能通过单一的"一键修复"按钮来实现,因为DLL文件缺失可能由各种不同的原因导致,比如应用程序安装不正确、病毒感染、或系统文件损坏等。 使用内置的系统文件检查器&#x…

鸿蒙应用布局ArkUI【基础运用案例】

布局基础运用案例 平级导航的复合网格视图 平级导航的复合网格视图常出现在同时展示多种不同内容的界面。 例如,市场类应用作为典型的平级导航,其首页不同板块采用了不同布局能力。 标题栏与搜索栏:因元素单一、位置固定在顶部&#xff0c…

C++ 中重写重载和隐藏的区别

重写(override)、重载(overload)和隐藏(overwrite)在C中是3个完全不同的概念。我们这里对其进行详细的说明 1、重写(override)是指派生类覆盖了基类的虚函数,这里的覆盖必…

【JAVA SE】初识JAVA

✨✨欢迎大家来到Celia的博客✨✨ 🎉🎉创作不易,请点赞关注,多多支持哦🎉🎉 所属专栏:JAVA 个人主页:Celias blog~ 目录 ​编辑 一、关于JAVA 1.1 JAVA语言简介 1.2 语言优势 1…

Patch-Wise Graph Contrastive Learning for Image Translation

Patch-Wise Graph Contrastive Learning for Image Translation 图像翻译中的逐块图对比学习 Chanyong Jung1, Gihyun Kwon1, Jong Chul Ye1, 2 Chanyong Jung,Gihyun Kwon,Jong Chul Ye 1, 2 Abstract 摘要 Patch-Wise Graph Cont…

Windows快捷命令

Windows 操作系统提供了大量的快捷命令,用于快速访问系统设置和管理工具。这些命令在各个版本的 Windows 中基本都适用,可以帮助用户快速进入各类管理工具,方便系统的配置和管理。如果你需要使用这些工具,只需按 Win R 键&#x…

win11快速安装mysql数据库系统

win11快速安装mysql数据库系统 1、下载 1.1 打开官网 1.2 向下滚动页面 1.3 进入下载选项 1.4 下载8.0.4 LTS 1.5 开始下载 1.6 下载中 2、解压 大家注意,此时解压后目录是没有data目录的。 3、数据库初始化 3.1 管理员身份打开CMD 开始菜单上,输入…

【漏洞复现】Secnet-智能路由系统弱口令

0x01 产品简介 Secnet安网智能AC管理系统是广州安网通信技术有限公司(简称“安网通信”)的无线AP管理系统 0x02 漏洞描述 攻击者可直接利用弱口令登录系统 0x03 搜索语法 fofa: title"安网-智能路由系统" || title"智能路由系统" || title"安网科…

代码随想录算法训练营第三十一天|455.分发饼干,376. 摆动序列,53. 最大子序和

455.分发饼干 优先把小饼干分给胃口值小的&#xff0c;或者是把大饼干分给胃口大的。 376. 摆动序列 class Solution { public:int wiggleMaxLength(vector<int>& nums) {if (nums.size() < 1) return nums.size();int curDiff 0; // 当前一对差值int preDiff …

PostgreSQL扩展之PGroonga:多语言全文搜索

简介 PGroonga 是一个 PostgreSQL 扩展&#xff0c;它增加了基于 Groonga 的全文搜索索引方法。虽然原生的 PostgreSQL 支持全文索引&#xff0c;但它仅限于基于字母和数字的语言。PGroonga 提供了更广泛的字符支持&#xff0c;使其成为 PostgreSQL 支持的语言的超集&#xff…

Ubuntu20.04调试功能包的一些报错解决办法【更新中2024.05.14】

一、Could not find a package configuration file provided by “catkin_virtualenv” 解决办法&#xff1a; sudo apt install ros-noetic-catkin-virtualenv二、 ERROR: Could not find a version that satisfies the requirement pip-tools5.1.2 (from versions: none) …

将PDF转换成电子杂志,轻松打造畅销内容!

在数字化时代&#xff0c;将PDF转换成电子杂志是一种非常受欢迎的内容创作方式。这种方式不仅可以提高内容的传播效果&#xff0c;还可以为创作者带来更多的收益。那么&#xff0c;如何轻松地将PDF转换成电子杂志&#xff0c;打造畅销内容呢&#xff1f; 市面上有许多可以将PDF…

战网国际服加速器用哪个好 暴雪战网好用加速器介绍

战网国际版&#xff0c;又称Battle.net环球版&#xff0c;是暴雪娱乐操盘的全球性游戏互动平台&#xff0c;它跨越地理界限&#xff0c;服务于全球游戏爱好者。与地区限定版本相异&#xff0c;国际版赋予玩家自由进入暴雪旗下众多经典游戏的权利&#xff0c;无论身处何方&#…

【Linux 网络】网络基础(二)(应用层协议:HTTP、HTTPS)-- 详解

我们程序员写的一个个解决我们实际问题&#xff0c;满足我们日常需求的网络程序&#xff0c;都是在应用层。 前面写的套接字接口都是传输层经过对 UDP 和 TCP 数据发送能力的包装&#xff0c;以文件的形式呈现给我们&#xff0c;让我们可以进行应用层编程。换而言之&#xff0c…