导读:@Import 和 @ImportResource或许很多人都用过,并且都还没有用错。但是若真把他俩拿过来一起的时候,却有点傻傻分不清楚了。总结本篇文章希望对从事相关工作的同学能够有所帮助或者启发
在平时看源码或者很多配置类上面都会出现@Import注解,功能就是和Spring XML 里面 的 一样. @Import注解是用来导入配置类或者一些需要前置加载的类.
一、背景
@Import和@ImportResource是的,他俩都有导入的含义,但是使用起来还是有很大的区别的,因此本文主要针对于他俩的区别,顺便从一定的原理的角度做一个解释,希望大家以后能区分开来。
在讲解之前,可以记住一个通用的的结论:
-
@Import主要用于导入类对象与另一个类对象的依赖;
-
@ImportResource主要用于在SpringBoot中显示指定从自定义的配置文件中生成bean而不是通过@Bean注解生成Bean
本文主要详解@Import 结合一些案例场景分析,后续有时间针对@Import 和 @ImportResource 进行对比讲解。总结本篇文章希望对从事相关工作的同学能够有所帮助或者启发。
二、@Import 注解解读
▐ 导读配置的三种类型
@Import支持 三种方式
-
带有@Configuration的配置类(4.2 版本之前只可以导入配置类,4.2版本之后 也可以导入普通类)
-
ImportSelector 的实现
-
ImportBeanDefinitionRegistrar 的实现
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
/**
* {@link Configuration @Configuration}, {@link ImportSelector},
* {@link ImportBeanDefinitionRegistrar},&nbs***bsp;regular component classes to import.
*/
Class<?>[] value();
}
二、@Import 案例实践
▐ 导入普通类
定义普通类
public class ABeanDefinition {
public String printName() {
return "类名 :" + Thread.currentThread().getStackTrace()[1].getClassName();
}
}
新建一个ImportConfig,在类上面加上@Configuration,加上@Configuration是为了能让Spring 扫描到这个类,并且直接通过@Import引入ABeanDefinition类
@Import({ABeanDefinition.class})
@Configuration
public class ImportConfiguration {
}
JUnit4测试结果
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = EngineSupportApplication.class)
public class ImportAnnotationInstance {
@Autowired(required = false)
ABeanDefinition aBeanDefinition;
@Autowired(required = false)
BBeanDefinition bBeanDefinition;
@Autowired(required = false)
CBeanDefinition cBeanDefinition;
@Autowired(required = false)
DBeanDefinition dBeanDefinition;
@Test
public void invokeADefaultMethod() {
System.out.println("A====================================");
System.out.println(aBeanDefinition.printName());
}
@Test
public void invokeBDefaultMethod() {
System.out.println("B====================================");
System.out.println(bBeanDefinition.printName());
}
@Test
public void invokeCDefaultMethod() {
System.out.println("C====================================");
System.out.println(cBeanDefinition.printName());
}
@Test
public void invokeDDefaultMethod() {
System.out.println("D====================================");
System.out.println(dBeanDefinition.printName());
}
}
▐ 导入带有@Configuration的配置类
定义带有@Configuration 的配置类
@Configuration
public class BBeanDefinition {
public String printName() {
return "类名 :" + Thread.currentThread().getStackTrace()[1].getClassName();
}
}
通过@Import引入BBeanDefinition类(4.2 版本之前只可以导入配置类,4.2版本之后 也可以导入普通类),高版本可省略此步骤。
@Import({BBeanDefinition.class})
public class ImportConfiguration {
}
JUnit4测试结果
▐ 通过ImportSelector 方式导入的类
定义测试类
public class CBeanDefinition {
public String printName() {
return "类名 :" + Thread.currentThread().getStackTrace()[1].getClassName();
}
}
新建SelfImportSelector.class 实现ImportSelector 接口,注入CBeanDefinition
public class SelfImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.alibaba.spring.annotations.CBeanDefinition"};
}
}
ImportConfiguration上面引入SelfImportSelector.class
@Import({SelfImportSelector.class})
@Configuration
public class ImportConfiguration {
}
JUnit4测试结果
▐ 通过 ImportBeanDefinitionRegistrar 方式导入的类
定义测试类
public class DBeanDefinition {
public String printName() {
return "类名 :" + Thread.currentThread().getStackTrace()[1].getClassName();
}
}
新建SelfImportBeanDefinitionRegistrar.class,实现接口ImportBeanDefinitionRegistrar,注入DBeanDefinition.class
public class SelfImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
RootBeanDefinition root = new RootBeanDefinition(DBeanDefinition.class);
registry.registerBeanDefinition("dBeanDefinition", root);
}
}
ImportConfiguration上面引入SelfImportBeanDefinitionRegistrar.class
@Import({DBeanDefinition.class})
@Configuration
public class ImportConfiguration {
}
JUnit4测试结果
三、总结
@Import 的使用如果基于内部项目来使用-用处不大,在高版本中完全可以使用@Configuration替换。但是当你项目里需要引用一些第三方的依赖,@Configuration注解的类包名都跟你不一样,包自动扫描就不会去自动加载。这个时候就需要@import了。
原文地址:Spring 中 @Import 注解三种使用场景解读
如果你觉的本文对你有帮助,麻烦点赞关注支持一下