参考文章:https://www.bilibili.com/video/BV1gW411W7wy?p=8
1. 简介
在Spring中,给容器注册组件有3种方式:
1、使用组件扫描 + 组件标注:@Component
、@Configuration
、@Controller
、@Service
、@Repository
。
2、在配置类中,使用 @Bean
。
3、使用@Import
。
@Import 的作用是给Spring容器快速注册组件,这个组件是使用 无参构造 创建出来的,是放在配置类(@Configuration
)上使用的。
2.使用方式
2.1 直接导入
在@Import
中直接写入需要导入的类 ,容器就会自动注册这个组件,id默认是全类名
使用案例:
BeanConfig.class
@Configuration
@Import({Color.class, Red.class})
public class BeanConfig {
}
Color.class
public class Color {
}
Red.class
public class Red {
}
2.2 实现 ImportSelector
选择并返回需要导入组件的 全类名 数组,所以这样可以一次 批量导入 多个组件。他只能返回全类名或者是空数组,绝对不能返回null,不然会空指针异常。
该接口里面有这一个方法:String[] selectImports(AnnotationMetadata importingClassMetadata)
。
返回值:导入到容器中的组件全类名数组。
AnnotationMetadata
:使用 @Import
注解 的类上的所有注解信息
使用案例:
MyImportSelector.class
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.entity.Blue", "com.entity.Yellow"};
}
}
BeanConfig.class:
@Configuration
@Import({Color.class, Red.class, MyImportSelector.class})
public class BeanConfig {
}
Blue.class
public class Blue {
}
Yellow.class
public class Yellow {
}
2.3 实现 ImportBeanDefinitionRegistrar
可以自己手动写 业务逻辑 来注册所需要的bean到容器中
该接口里面有这一个方法:void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry)
AnnotationMetadata
:使用 @Import
注解 的类上的所有注解信息
BeanDefinitionRegistry
:BeanDefinition
的注册类,我们把所有需要添加到容器中的bean,调用里面的void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
方法即可注册。
案例:
容器中有 Yellow 和 Red 才注册 RainBow
MyImportBeanDefinitionRegistrar.class
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean yellow = registry.containsBeanDefinition("com.entity.Yellow");
boolean red = registry.containsBeanDefinition("com.entity.Red");
if (yellow && red){
//指定Bean的定义信息(Bean类型、作用域等)
RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class);
//指定Bean名 与 Bean定义信息
registry.registerBeanDefinition("rainbow",beanDefinition);
}
}
}
BeanConfig.class
@Configuration
@Import({Color.class, Red.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class BeanConfig {
}
RainBow.class
public class RainBow {
}
3.总结
在SpringBoot中,大量使用了 @Import
注解,特别是使用 实现 ImportSelector 的方法来注册组件,日后需要看懂SpringBoot源码,学会 @Import
很重要