@Import详解及@Import注入对象的四种方式

news/2024/10/18 9:46:25/

在Java中,@Import注解是用于引入其他配置类或Bean的注解。它可以帮助将特定的配置类或Bean注册到Spring容器中,使其可供应用程序使用。

@Import详解

  @Import注解可以用在@Configuration注解的类上,也可以用在普通的类上。它作为一个元注解,可以标记其他注解,例如@ImportResource@ImportSelector@ImportBeanDefinitionRegistrar等。

使用@Import注解,可以将以下内容导入到Spring容器中:

  1. 配置类(Configuration Class):通过导入其他的配置类,可以将其内部定义的Bean注册到容器中。
  2. 普通类(Non-configuration Class):将普通的类作为Bean导入到Spring容器中。

@Import源码


@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {/*** {@link Configuration @Configuration}, {@link ImportSelector},* {@link ImportBeanDefinitionRegistrar}, or regular component classes to import.*/Class<?>[] value();}

从注释来看,@Import注解只可以标注在类上,可以结合 @Configuration注解、ImportSelector、ImportBeanDefinitionRegistrar一起使用,也可以导入普通的类。

因此,@Import的使用方式有4种:直接导入类,导入配置类来导入Bean,导入 ImportSelector 的实现类,导入 ImportBeanDefinitionRegister 的实现类。需要注意的是:ImportSelector、ImportBeanDefinitionRegistrar 这两个接口都必须依赖于 @Import 一起使用,而 @Import 可以单独使用。

@Import的实现原理

@Import注解的实现原理涉及到Spring框架的组件扫描、Bean注册和依赖注入等机制

  1. 组件扫描:Spring框架会通过组件扫描机制,自动扫描并加载带有@Configuration注解或其他指定注解的配置类,将它们识别为配置类。

  2. 注册配置类:当一个配置类被识别后,Spring会将其实例化为一个Bean,并将其注册到容器中。这样,配置类内部定义的所有Bean都可以由Spring容器进行管理。

  3. 处理@Import注解:当在配置类上使用@Import注解时,Spring会解析注解的参数,根据参数的不同类型进行相应的处理。

    • 导入其他配置类:如果@Import的参数是其他配置类(例如@Configuration注解的类),Spring会将导入的配置类也加入到容器中,使得被导入的配置类内部定义的Bean也可以被管理。

    • 导入普通类:如果@Import的参数是普通类,则Spring会将该类实例化为一个Bean,并注册到容器中。

    • 导入实现了ImportSelector的类:如果@Import的参数是实现了ImportSelector接口的类,Spring会调用ImportSelector接口的selectImports()方法,根据返回的类名数组将相应的类注册为Bean。这样,可以根据特定的逻辑动态选择需要导入的类。

    • 导入实现了ImportBeanDefinitionRegistrar的类:如果@Import的参数是实现了ImportBeanDefinitionRegistrar接口的类,Spring会调用ImportBeanDefinitionRegistrar接口的registerBeanDefinitions()方法,通过编程方式注册Bean定义到容器中。这样,可以通过自定义的逻辑来注册额外的Bean。

        通过以上步骤,@Import注解使得我们能够方便地导入其他配置类、普通类或实现了ImportSelectorImportBeanDefinitionRegistrar接口的类,并将它们注册到Spring容器中,从而实现Bean的管理和依赖注入。

需要导入的类


public class HelloImport {public void test() {System.out.println("hello JF");}
}

1、直接导入类

@Import(HelloImport.class)
public class SpringTestApplication {public static void main(String[] args) {//1.通过AnnotationConfigApplicationContext创建spring容器,参数为@Import标注的类ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringTestApplication.class);HelloImport helloImport = applicationContext.getBean(HelloImport.class);elloImport.test();}
}

项目中常用以下方式:


@Import(HelloImport.class)
@Configuration
public class ConfigTest { 
}

2、导入配置类注入Bean

@Configuration
public class HelloImportConfiguration {@Beanpublic HelloImport helloImport() {return new HelloImport();}
}@Import(HelloImportConfiguration.class)
public class SpringTestApplication {public static void main(String[] args) {ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringTestApplication.class);HelloImport helloImport = applicationContext.getBean(HelloImport.class);helloImport.test();}
}

这种方式的使用场景是配置类无法被直接扫描到。

3、导入 ImportSelector 实现类

ImportSelector是一个接口,实现这个接口需要重写selectImports方法。selectImports方法会返回一个String数组,它包含的元素是需要被导入到容器中的类的全限定名。


public class HelloImportSelector implements ImportSelector {/*** 返回需要导入的类名的数组,可以是任何普通类,配置类(@Configuration、@Bean、@CompontentScan等标注的类)* @importingClassMetadata:用来获取被@Import标注的类上面所有的注解信息*/@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {List list = new ArrayList<>();list.add("intl.skw.test.HelloImport");return StringUtils.toStringArray(list);}
}@Import(HelloImportSelector.class)
public class SpringTestApplication {public static void main(String[] args) {ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringTestApplication.class);HelloImport helloImport = applicationContext.getBean(HelloImport.class);helloImport.test();}
}

4、导入 ImportBeanDefinitionRegistrar 实现类

当类实现了 ImportBeanDefinitionRegistrar 接口,就可以拿到注册器,可以向容器中注册任何的Bean,并且可以对Bean添加属性。

public class HelloImportDefinitionRegistrar implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(HelloImport.class).getBeanDefinition();registry.registerBeanDefinition("HelloImport", beanDefinition);}
}@Import(HelloImportDefinitionRegistrar.class)
public class SpringTestApplication {public static void main(String[] args) {ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringTestApplication.class);HelloImport helloImport = applicationContext.getBean(HelloImport.class);helloImport.test();}
}


http://www.ppmy.cn/news/581881.html

相关文章

用API Key保护Spring Boot 接口的安全

1、概述 安全性在REST API开发中扮演着重要的角色。一个不安全的REST API可以直接访问到后台系统中的敏感数据。因此&#xff0c;企业组织需要关注API安全性。 Spring Security 提供了各种机制来保护我们的 REST API。其中之一是 API 密钥。API 密钥是客户端在调用 API 调用时提…

2022哪款蓝牙耳机性价比高?高品质蓝牙耳机测评

在蓝牙耳机的横空出世的时候&#xff0c;受到很多年轻人的追捧&#xff0c;各大网络都上新了蓝牙耳机&#xff0c;因为蓝牙耳机在现在的社会生活中必不可少。下面小编为大家整理的蓝牙耳机好评榜&#xff0c;推荐几款小编觉得品质比较高的几款耳机吧&#xff01; 第一款&#…

哪家蓝牙耳机性价比高?总结知乎力荐的这五款蓝牙耳机

如今蓝牙技术的火速发展&#xff0c;也产生了不少音质好、质量佳的耳机品牌&#xff0c;喜欢音乐的小伙伴经常陶醉于声音带来的美感当中。对于蓝牙耳机的要求除了音质&#xff0c;一些新的功能也会提高耳机使用带来的满足感&#xff0c;比如主动降噪&#xff0c;比如语音控制等…

力扣日记1401

1. 题目 LeetCode 1401. 圆和矩形是否有重叠 1.1 题意 给定圆和矩形&#xff0c;判断两个图形是否有重叠部分 1.2 分析 两个图形重叠有两种情况&#xff0c;相交和包含。 先考虑相交&#xff1a;相交的话圆至少和矩形的某条边有交点&#xff0c;因为矩形四条边都平行/重合于…

Mysql之回表

文章目录 什么是回表为什么会回表怎么避免回表 什么是回表 当需要查询的数据在索引树中不存在的时候&#xff0c;需要再次到聚集索引中去获取&#xff0c;这个过程就叫回表。 更简单点就是&#xff1a;先定位主键值&#xff0c;再定位行纪录。 那什么是聚集索引呢&#xff1…

SSM山西能源学院教室管理系统-计算机毕设 附源码81671

SSM山西能源学院教室管理系统 摘 要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;山西能源学院教室管理系统当然也不能排除在外。山西能源学院教室管理系统是以实际运用为…

股票量化分析工具QTYX使用攻略——涨停个股挖掘热门板块(更新2.6.6)

搭建自己的量化系统 如果要长期在市场中立于不败之地&#xff01;必须要形成一套自己的交易系统。 行情不等人&#xff01;边学习边实战&#xff0c;在实战中学习才是最有效地方式。于是我们分享一个即可以用于学习&#xff0c;也可以用于实战炒股分析的量化系统——QTYX。 QTY…

Axure教程—中继器筛查与排序

当工作中需要进行数据筛查排序操作时&#xff0c;我们可以如何使用Axure来进行相关操作呢&#xff1f;本篇文章里&#xff0c;作者利用中继器为我们展示了数据筛查与排序&#xff0c;让我们一起来看一下。 预览效果 预览地址&#xff1a;https://6q6ajh.axshare.com 功能介绍…