关于@Import注解的几个问题
本文来说下关于@Import注解的几个问题
文章目录
- 概述
- 导入配置的三种类型
- 源码解释
- 测试例子
- 导入普通类
- 导入带有@Configuration的配置类
- 通过ImportSelector 方式导入的类
- 通过 ImportBeanDefinitionRegistrar 方式导入的类
- 本文小结
概述
在平时看源码或者很多配置类上面都会出现@Import注解,功能就是和Spring XML 里面 的 一样. @Import注解是用来导入配置类或者一些需要前置加载的类.。
导入配置的三种类型
@Import支持 三种方式
- 带有@Configuration的配置类(4.2 版本之前只可以导入配置类,4.2版本之后 也可以导入 普通类)
- ImportSelector 的实现
- ImportBeanDefinitionRegistrar 的实现
这些用法或许只有一个目的,就是导入Bean。那为什么要这么麻烦,手动导入Bean呢,@ComponentScan不是可以自动扫描包注册Bean嘛?
其实这里的原因有两点:
- @ComponentScan一般只会扫到自己项目中的Bean,第三方jar包中的@Bean扫不到。
- @Import注解可以结合@Conditional注解使用,即条件导入,@Conditional在spring源码中也是大量用到,这个我后面会专题介绍。
源码解释
源码解释
/*** Indicates one or more {@link Configuration @Configuration} classes to import.* *功能类似XML 里面的 <import/> ,可以导入 @Configuration配置类,ImportSelector、* ImportBeanDefinitionRegistrar 的实现,4.2 版本之后可以导入普通类(类似AnnotationConfigApplicationContext#register* )* <p>Provides functionality equivalent to the {@code <import/>} element in Spring XML.* Allows for importing {@code @Configuration} classes, {@link ImportSelector} and* {@link ImportBeanDefinitionRegistrar} implementations, as well as regular component* classes (as of 4.2; analogous to {@link AnnotationConfigApplicationContext#register}).** 可以在类级别声明或作为元注释声明* <p>May be declared at the class level or as a meta-annotation.* 如需要引入XML或其他类型的文件,使用@ImportResource注解* <p>If XML or other non-{@code @Configuration} bean definition resources need to be* imported, use the {@link ImportResource @ImportResource} annotation instead.*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {/*** {@link Configuration}, {@link ImportSelector}, {@link ImportBeanDefinitionRegistrar}* or regular component classes to import.*/Class<?>[] value();}
测试例子
导入普通类
新建一个TestA
package cn.wideth.test;public class TestA {public void printName() {System.out.println("类名 :" + Thread.currentThread().getStackTrace()[1].getClassName());}
}
新建一个ImportConfig,在类上面加上@Configuration,加上@Configuration是为了能让Spring 扫描到这个类,并且直接通过@Import引入TestA类
package cn.wideth.test;import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;@Import({TestA.class})
@Configuration
public class ImportConfig {}
TestA 是一个普通的类,现在可以被@Autowired注释然后调用,就直接说明已经被Spring 注入并管理了,普通的类都是需要先实例化
package cn.wideth.test;import cn.wideth.PdaAndIpadApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)
@SpringBootTest(classes = PdaAndIpadApplication.class)
public class ImportAnnotationTest {@Autowiredprivate TestA testA;@Testpublic void TestA() {testA.printName();}
}
测试结果
导入带有@Configuration的配置类
新建TestB
package cn.wideth.test;import org.springframework.context.annotation.Configuration;@Configuration
public class TestB {public void printName() {System.out.println("类名 :" + Thread.currentThread().getStackTrace()[1].getClassName());}
}
在ImportConfig.class里面直接引入TestB
package cn.wideth.test;import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;@Import({TestB.class})
@Configuration
public class ImportConfig {}
测试结果 TestB.class 的类上面已经有了@Configuration注解,本身就会配spring扫到并实例,@import引入带有@Configuration的配置文件,是需要先实例这个配置文件再进行相关操作
package cn.wideth.test;import cn.wideth.PdaAndIpadApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)
@SpringBootTest(classes = PdaAndIpadApplication.class)
public class ImportAnnotationTest {@Autowiredprivate TestB testb;@Testpublic void TestB() {testb.printName();}
}
程序结果
通过ImportSelector 方式导入的类
新建TestC.class
package cn.wideth.test;public class TestC {public void printName() {System.out.println("类名 :" + Thread.currentThread().getStackTrace()[1].getClassName());}
}
新建SelfImportSelector.class 实现ImportSelector 接口,注入TestC.class
package cn.wideth.test;import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;public class SelfImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{"cn.wideth.test.TestC"};}
}
ImportConfig上面引入SelfImportSelector.class
package cn.wideth.test;import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;@Import({SelfImportSelector.class})
@Configuration
public class ImportConfig {}
测试程序
package cn.wideth.test;import cn.wideth.PdaAndIpadApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)
@SpringBootTest(classes = PdaAndIpadApplication.class)
public class ImportAnnotationTest {@Autowiredprivate TestC testc;@Testpublic void TestC() {testc.printName();}
}
测试结果
通过 ImportBeanDefinitionRegistrar 方式导入的类
新建TestD.class
package cn.wideth.test;public class TestD {public void printName() {System.out.println("类名 :" + Thread.currentThread().getStackTrace()[1].getClassName());}
}
新建SelfImportBeanDefinitionRegistrar.class,实现接口ImportBeanDefinitionRegistrar,注入TestD.class
package cn.wideth.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 SelfImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {RootBeanDefinition root = new RootBeanDefinition(TestD.class);registry.registerBeanDefinition("testd", root);}
}
ImportConfig类上加上导入SelfImportBeanDefinitionRegistrar.class
package cn.wideth.test;import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;@Import({SelfImportBeanDefinitionRegistrar.class})
@Configuration
public class ImportConfig {}
测试程序
package cn.wideth.test;import cn.wideth.PdaAndIpadApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)
@SpringBootTest(classes = PdaAndIpadApplication.class)
public class ImportAnnotationTest {@Autowiredprivate TestD testd;@Testpublic void testd() {testd.printName();}
}
测试结果
本文小结
本文详细介绍了@Import注解相关的知识与内容。
关于@Import注解的几个问题相关推荐
- Spring Boot 关于 @Import注解 —— 导入资源
@Import 在应用中,有时没有把某个类注入到IOC容器中,但在运用的时候需要获取该类对应的bean,此时就需要用到@Import注解. 示例如下: 先创建两个类,不用注解注入到IOC容器中,在应用 ...
- @import注解使用
今天主要从以下几方面来介绍一下@Import注解 @Import注解是什么 @Import的三种使用方式 1,@Import注解是什么 通过导入的方式实现把实例加入springIOC容器中 2,@Im ...
- Spring中@Import注解的作用和使用
查看Import注解源码 作用: 1.声明一个bean 2. 导入@Configuration注解的配置类 3.导入ImportSelector的实现类 4.导入ImportBeanDefinitio ...
- idea去掉无用import类_@Import注解的魅力
本篇主要介绍Spring注解@Import的魅力所在:它能让你高度自由的定义配置类装载规则与Bean注册逻辑.@Import是Spring体系中的一个比较重要的注解,下面让我们一起看看它都有哪些神奇的 ...
- 五、Spring中的@Import注解
一.使用@Import注解导入组件 @Import注解的作用是给容器中导入组件,回顾下我们给容器中导入组件的方式,可以通过Spring的xm配置方式,可以通过注解,如@Component等,也可以通过 ...
- 通过@Import注解把类注入容器的四种方式
文章目录 1. @Import导入的四种方式 2. 准备工作 ①:导入普通类ConfigA ②:导入`@Configuration`配置类ConfigB ③:导入`ImportSelector`的实现 ...
- java的 import注解_[java]一分钟学会spring注解之@Import注解
今天主要从以下几方面来介绍一下@Import注解 @Import注解是什么 @Import的三种使用方式 1,@Import注解是什么 通过导入的方式实现把实例加入springIOC容器中 2,@Im ...
- spring注解之@Import注解的三种使用方式
1.@Import注解须知 1.@Import只能用在类上 ,@Import通过快速导入的方式实现把实例加入spring的IOC容器中 2.加入IOC容器的方式有很多种,@Import注解就相对很牛皮 ...
- @Import注解使用及源码分析
1.简介 在阅读spring源码的时候,当读到解析@configuration这个注解的时候,发现其中解析到一个很重要的注解叫做@Import,可能很多人没有听过,没有翻阅源码的时候也是不知所云,其实 ...
最新文章
- c++ vscode 第三方库_Windows平台配置VSCode的C/C++环境,超清晰
- css3效果: animate实现点点点loading动画效果(一)
- 关于git fetch 和git pull 的区别
- 学了这四招,你在Linux上观看Netflix视频不发愁
- 2019牛客暑期多校训练营(第七场)J A+B problem
- SQL 查找是否存在,别再 count 了,很耗费时间的!
- Mac远程连接Windows的远程桌面服务
- c++真的比java难吗_开课吧Java课程怎么样?开课吧的Java课程真的那么好吗?
- 英语介词at、in、on常见用法(时间、地点、方位)
- BZOJ3772精神污染
- SND: 项目发布时Owning ClassInfo is null for property: private问题原因排查与解决
- Opencv中使用ocl模块遇到的问题
- java捕鱼达人_java捕鱼达人游戏(源码)
- C51模拟PS2键盘(三)
- 高职计算机专业英语词汇,职高英语单词复习
- 北信源内网安全与补丁分发系统简单功能介绍
- 计算机语言与智能家居的关系,来谈谈“智能家居”与“家庭自动化”的区别
- python怎么安装scrapy_windows下安装python+scrapy
- VUE_关于Vue.use()详解
- 案例11-生产环境重大事故