1、简介
@Import快速给容器中导入一个组件。
2、基础类
public class Color {}
public class Black {}
public class Blue {}
public class Red {}
public class Yellow {}
3、@Import
3.1、取值
Class<?>[] value();
有三种可以指定:
1、直接写被导入的class
2、ImportSelector
3、ImportBeanDefinitionRegistrar
3.2、作用域
作用到类上。
3.3、讲解
3.3.1、概述
@Import快速给容器中导入一个组件。默认组件id为全类名。
3.3.2、需求一
利用@Import导入Color和Red组件。
3.3.3、配置类
@Configuration
/**
* @Import 导入组件,id默认是组件的全类名(com.chentongwei.spring.annotation.Import.entity.Color)
*/
@Import({Color.class, Red.class})
public class MainConfig {
/**
* 给容器中注册组件:
* 1)、包扫描+组件标注注解(@ComponentScan)
* 2)、@Bean【导入的第三方包里面的组件】
* 3)、@Import【快速给容器中导入一个组件】
* 3.1)、@Import({要导入容器中的组件})。
* 3.2)、ImportSelector:返回需要导入的组件的全类名的子数组
* 3.3)、MyImportBeanDefinitionRegistrar:手工注册bean到容器中
*/
}
3.3.4、测试类
public class ImportTest {
private final ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
@Test
public void test1() {
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String name : beanDefinitionNames) {
System.out.println(name);
}
}
}
3.3.5、测试结果
mainConfig
com.chentongwei.spring.annotation.Import.entity.Color
com.chentongwei.spring.annotation.Import.entity.Red
PS:
结果分析:
帮我们注入了Color和Red的组件,并且id为全类名。
3.3.6、需求二
如我们还有两个类要导入,我们可以继续往@Import里追加进去,但是很麻烦啊,一坨类,有没有看着清爽点的办法呢?有的,借助ImportSelector接口。
3.3.7、selector
public class MyImportSelector implements ImportSelector {
/**
* 自定义逻辑返回需要导入的组件的数组
*
* @param importingClassMetadata:当前标注@Import注解的所有注解信息
* @return: 要导入到容器中的组件的全类名
*/
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[] {"com.chentongwei.spring.annotation.Import.entity.Blue", "com.chentongwei.spring.annotation.Import.entity.Yellow"};
}
}
PS:
自定义selector需要实现ImportSelector接口并重写selectImports方法。
3.3.8、配置类
@Configuration
/**
* @Import 导入组件,id默认是组件的全类名(com.chentongwei.spring.annotation.Import.entity.Color)
*/
@Import({Color.class, Red.class, MyImportSelector.class})
public class MainConfig {
/**
* 给容器中注册组件:
* 1)、包扫描+组件标注注解(@ComponentScan)
* 2)、@Bean【导入的第三方包里面的组件】
* 3)、@Import【快速给容器中导入一个组件】
* 3.1)、@Import({要导入容器中的组件})。
* 3.2)、ImportSelector:返回需要导入的组件的全类名的子数组
* 3.3)、MyImportBeanDefinitionRegistrar:手工注册bean到容器中
*/
}
3.3.8、测试类
public class ImportTest {
private final ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
@Test
public void test1() {
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String name : beanDefinitionNames) {
System.out.println(name);
}
}
}
3.3.9、测试结果
mainConfig
com.chentongwei.spring.annotation.Import.entity.Color
com.chentongwei.spring.annotation.Import.entity.Red
com.chentongwei.spring.annotation.Import.entity.Blue
com.chentongwei.spring.annotation.Import.entity.Yellow
PS:
结果分析:
我们可以发现我们只导入了
MyImportSelector
却自动给我们注入了Blue和Yellow,这样的话就很好了,我们可以单独起一个类来管理需要被导入的组件,不乱。
3.3.10、需求三
我们可能需要做一些判断才能导入bean,比如:我要判断目前的被导入的组件中是否包含Blue和Red,若包含,则导入Black组件,否则不导入Black组件。
3.3.11、registrar
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/**
* @param importingClassMetadata:当前类注解信息
* @param registry:BeanDefinition注册类,把所有需要添加到容器中的bean,调用BeanDefinitionRegistry.registerBeanDefinition手工注册进来
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean red = registry.containsBeanDefinition("com.chentongwei.spring.annotation.Import.entity.Red");
boolean blue = registry.containsBeanDefinition("com.chentongwei.spring.annotation.Import.entity.Blue");
if (red && blue) {
// 指定bean的id以及bean的定义信息
registry.registerBeanDefinition("black", new RootBeanDefinition(Black.class));
}
}
}
PS:
需要实现ImportBeanDefinitionRegistrar的接口并重写registerBeanDefinitions方法。
3.3.12、配置类
@Configuration
/**
* @Import 导入组件,id默认是组件的全类名(com.chentongwei.spring.annotation.Import.entity.Color)
*/
@Import({Color.class, Red.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class MainConfig {
/**
* 给容器中注册组件:
* 1)、包扫描+组件标注注解(@ComponentScan)
* 2)、@Bean【导入的第三方包里面的组件】
* 3)、@Import【快速给容器中导入一个组件】
* 3.1)、@Import({要导入容器中的组件})。
* 3.2)、ImportSelector:返回需要导入的组件的全类名的子数组
* 3.3)、MyImportBeanDefinitionRegistrar:手工注册bean到容器中
*/
}
3.3.13、测试类
public class ImportTest {
private final ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
@Test
public void test1() {
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String name : beanDefinitionNames) {
System.out.println(name);
}
}
}
3.3.14、测试结果
mainConfig
com.chentongwei.spring.annotation.Import.entity.Color
com.chentongwei.spring.annotation.Import.entity.Red
com.chentongwei.spring.annotation.Import.entity.Blue
com.chentongwei.spring.annotation.Import.entity.Yellow
black
PS:
结果分析:
Black组件自动为我们注入了进来,并且id为自定义的black
3.4、注意
SpringBoot底层大量运用了@Import注解。
4、广告
-
码云点star,万分感谢!
代码已经上传到码云了
https://gitee.com/geekerdream/spring-anonation
通用的权限处理框架
https://gitee.com/geekerdream/common-security
通用的异常处理
https://gitee.com/geekerdream/exception-handler
通用的发送邮件
https://gitee.com/geekerdream/common-boot-email
陆续会推出更多干货,希望关注!
-
QQ群【Java初学者学习交流群】:458430385
-
微信公众号【Java码农社区】
- 今日头条号:编程界的小学生
网友评论