1.Import定义:
往容器中注册bean
使用须知:
1、@Import只能用在类上 ,@Import通过快速导入的方式实现把实例加入spring的IOC容器中
2、加入IOC容器的方式有很多种,@Import注解就相对很牛皮了,@Import注解可以用于导入第三方包 ,当然@Bean注解也可以,但是@Import注解快速导入的方式更加便捷
3、@Import注解有三种用法
2.使用方法:
有三种使用方式
1、直接填class数组方式
2、ImportSelector方式【重点】
3、ImportBeanDefinitionRegistrar方式
2.1直接填class数组方式
创建Dog类,Cat类
public class Dog {
}
public class Cat {
}
创建配置类MainConfig,注解中加入Dog,Cat类数组:@Import(value = {Dog.class, Cat.class})
@Configuration
@Import(value = {Dog.class, Cat.class})
public class MainConfig {
/**
* 给容器中注册组件(bean)的方式
* 1.@Bean:[导入第三方的类或组件],比如Person为第三方的类,需要在容器中使用
* 2.包扫描+组件的标注注解(@componentScan:@Controller,@Service,@Reponsitory,@Componet),一般是针对我们自己写的类
* 3。@Import:【快速给容器导入组件】
*
* @return
*/
@Bean
public Person person(){
System.out.println("给容器中 添加person........");
return new Person("JJJ",12);
}
}
创建测试类,遍历打印bean名称
@Test
public void test01(){
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
System.out.println("IOC容器创建完成.....");
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
}
测试结果:
import的bean都加入到spring容器中,这些在容器中bean名称是该类的全类名 ,比如com.enjoy.cap6.config.bean.类名
2.2 ImportSelector方式
新建两个类Fish,Pig
新建一个MyImportSelector类实现ImportSelector接口,返回的bean需要写全类名,否则不能识别。
public class MyImportSelector implements ImportSelector {
/**
* selectImports方法可以返回空数组但是不能返回null,否则会报空指针异常!
* @param annotationMetadata
* @return
*/
public String[] selectImports(AnnotationMetadata annotationMetadata) {
//返回全类名的bean
return new String[]{"com.enjoy.cap6.bean.Fish","com.enjoy.cap6.bean.Pig"};
}
}
修改配置类,加入自定义的MyImportSelector类
@Import(value = {Dog.class, Cat.class, MyImportSelector.class})
public class MainConfig {
/**
* 给容器中注册组件(bean)的方式
* 1.@Bean:[导入第三方的类或组件],比如Person为第三方的类,需要在容器中使用
* 2.包扫描+组件的标注注解(@componentScan:@Controller,@Service,@Reponsitory,@Componet),一般是针对我们自己写的类
* 3. @Import:【快速给容器导入组件】
* a.@Import(XX.class):容器会自动注册这个组件,组件名为全类名
* b.@ImportSelector:是一个接口,返回需要导入到容器的组件的全类名数组
* 注意:selectImports方法可以返回空数组但是不能返回null,否则会报空指针异常!
* @return
*/
@Bean
public Person person(){
System.out.println("给容器中 添加person........");
return new Person("JJJ",12);
}
}
运行测试类:
2.3 ImportBeanDefinitionRegistrar方式
新建一个MyImportBeanDefinitionRegistrar类实现ImportBeanDefinitionRegistrar接口
举例:如果如果Dog和Cat同时存在于容器中,把Tiger注册进容器
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/**
*
* @param importingClassMetadata:当前被@Import注解给标注的所有注解信息
* @param registry:BeanDefinition注册类,用于注册定义一个bean
* 把所有需要加入容器的bean加入
*/
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean c = registry.containsBeanDefinition("com.enjoy.cap6.bean.Cat");
boolean d = registry.containsBeanDefinition("com.enjoy.cap6.bean.Dog");
//如果Dog和Cat同时存在于容器中,把Tiger注册进容器
if(c && d ){
//对于要注册的bean,需要对bean进行封装
//指定bean定义信息(包括bean的类型、作用域...)
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Tiger.class);
//注册一个bean指定bean名字(id)
registry.registerBeanDefinition("tiger",rootBeanDefinition);
}
}
}
修改配置类,在Import数组后追加MyImportBeanDefinitionRegistrar.class
//配置类 == 配置文件xml
@Configuration
@Import(value = {Dog.class, Cat.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class MainConfig {
/**
* 给容器中注册组件(bean)的方式
* 1.@Bean:[导入第三方的类或组件],比如Person为第三方的类,需要在容器中使用
* 2.包扫描+组件的标注注解(@componentScan:@Controller,@Service,@Reponsitory,@Componet),一般是针对我们自己写的类
* 3. @Import:【快速给容器导入组件】
* a.@Import(XX.class):容器会自动注册这个组件,组件名为全类名
* b.@ImportSelector:是一个接口,返回需要导入到容器的组件的全类名数组
* 注意:selectImports方法可以返回空数组但是不能返回null,否则会报空指针异常!
* c.@ImportBeanDefinitionRegistrar:可以手动添加组件到ioc容器,所有bean的注册都可以使用ImportBeanDefinitionRegistrar
* 实现ImportBeanDefinitionRegistrar接口即可
* @return
*/
@Bean
public Person person(){
System.out.println("给容器中 添加person........");
return new Person("JJJ",12);
}
}
运行测试类:
tiger被注册进容器中了
3.总结:
第一种用法:@Import({ 要导入的容器中的组件 } ):容器会自动注册这个组件,id默认是全类名
第二种用法:ImportSelector:返回需要导入的组件的全类名数组,springboot底层用的特别多【重点 】
第三种用法:ImportBeanDefinitionRegistrar:手动注册bean到容器
以上三种用法方式皆可混合在一个@Import中使用,特别注意第一种和第二种都是以全类名的方式注册,而第三中可自定义方式。