Spring @Import 注解用法
原文(简单修改):Spring 注解之 @Import 注解的三种使用方式
1、@Import 注解简介
@Import 只能用在类上,用于把实例加入 Spring 的 IOC 容器中。
下面是 @Import 注解的定义,其接收一个 Class 数组类型的参数:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Import { Class<?>[] value(); }
@Import 注解有三种用法,包括:
-
直接填 Class 数组方式
-
ImportSelector 方式【重点】
-
ImportBeanDefinitionRegistrar 方式
2、@Import 的三种用法
2.1、第一种用法:直接填 Class 数组
直接填对应的 Class 数组,Class 数组可以有 0 到多个。语法如下:
@Import({ 类名.class, 类名.class... }) public class TestDemo { }
Spring 将按传给 @Import 注解的 Class 初始化实例并将其加入到 Spring 容器中,bean 名称是该类的全类名。
2.2、第二种用法:ImportSelector 方式【重点】
这种方式的前提就是一个类要实现 ImportSelector 接口。比如创建 MyImportSelector 类并实现 ImportSelector 接口:
public class MyImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata annotationMetadata) { return new String[0]; } }
分析:
- selectImports 方法的返回值就是我们实际上要导入到容器中的组件全类名数组【重点】
- 其参数 AnnotationMetadata 表示当前被 @Import 注解给标注的所有注解信息
需要注意的是 selectImports 方法可以返回空数组但是不能返回 null,否则会报空指针异常。
具体用法如下:
第一步:创建 MyImportSelector 类并实现 ImportSelector 接口,这里用于演示就添加一个全类名给其返回值:
public class MyImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata annotationMetadata) { return new String[]{"com.example.Test.TestDemoBean"}; } }
第二步:编写 TestDemo 类,并标注上使用 ImportSelector 方式的 MyImportSelector 类:
@Configuration @Import({MyImportSelector.class}) public class TestDemo { }
第三步:编写打印容器中的组件测试类:
/** * 打印容器中的组件测试 */ public class AnnotationTestDemo { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(TestDemo.class); // 这里的参数代表要做操作的类 String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames(); for (String name : beanDefinitionNames){ System.out.println(name); } } }
运行结果将会看到 TestDemoBean 这个类,因为 @Import 注解的参数是数组,所以可以同时导入多个类,这里只导入了一个类。
2.3、第三种用法:ImportBeanDefinitionRegistrar 方式
同样是一个接口,类似于第二种 ImportSelector 用法,相似度 80%,只不过这种更灵活,具体如下:
第一步:创建 MyBeanDefinitionRegistrar 类并实现 ImportBeanDefinitionRegistrar 接口
public class MyBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { // 该实现方法默认为空 @Override public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) { } }
参数分析:
- 第一个参数:annotationMetadata 和之前的 ImportSelector 参数一样都是表示当前被 @Import 注解给标注的所有注解信息
- 第二个参数表示用于注册 bean
第二步:编写代码,自定义注册 bean
public class MyBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) { // 指定 bean 定义信息(包括 bean 的类型、作用域...) RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(TestDemoBean.class); // 注册一个 bean 指定 bean 名字(id) beanDefinitionRegistry.registerBeanDefinition("TestDemoBean", rootBeanDefinition); } }
第三步:编写 TestDemo 类,并标注上使用 ImportBeanDefinitionRegistrar 方式的 MyBeanDefinitionRegistrar 类
@Import({MyBeanDefinitionRegistrar.class}) public class TestDemo { }
运行后,容器中就会有 TestDemoBean 这个 bean,id 为 TestDemoBean。
3、@Import 注解的三种使用方式总结
第一种用法:@Import({ 类名.class, 类名.class... })
:容器会自动注册类对应 bean,id 默认是全类名。
第二种用法:ImportSelector
:返回需要导入的组件的全类名数组,SpringBoot 底层用得特别多【重点】。
第三种用法:ImportBeanDefinitionRegistrar
:手动注册 bean 到容器。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~