@Import:导入bean的实例,是bean注入的一种的一种形式,默认的bean的id是全类名
@Import注解,我们先看定义;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
/**
* {@link Configuration}, {@link ImportSelector}, {@link ImportBeanDefinitionRegistrar}
* or regular component classes to import.
*/
Class<?>[] value();
}
可以像@Configuration导入类或者组件,导入类,分三种
1:直接导入普通的类
2.导入实现了ImportSelector接口的类
3:导入实现了ImportBeanDefinitionRegistrar接口的类
我们三种都可以尝试一下:创建ImportSelector和ImportBeanDefinitionRegistrar的实现类
public class MyImportSelector implements ImportSelector {
/**
* AnnotationMetadata:当前标注@Import注解的类的所有注解信息(debug的时候,可以直接看到)
*/
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
// 方法不要返回null值 返回值,就是到导入到容器中的组件全类名
return new String[] { "java.util.Date", "java.util.ArrayList" };
}
}
实现ImportBeanDefinitionRegistrar接口的时候,重写了
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry)
BeanDefinitionRegistry 跟上面重写Condition接口,拿到的是一样的,可以获取容器中的类的信息,以及手动注入一个bean
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/**
* AnnotationMetadata:当前类的注解信息
* BeanDefinitionRegistry:BeanDefinition注册类; 把所有需要添加到容器中的bean;调用
* BeanDefinitionRegistry.registerBeanDefinition手工注册进来
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 指定Bean定义信息;(Bean的类型,Bean。。。)
RootBeanDefinition beanDefinition = new RootBeanDefinition(Red.class);
// 注册一个Bean,指定bean名
registry.registerBeanDefinition("red", beanDefinition);
}
}
使用代码如下:需要注意,为了简便,我是重复注入了好几个一样的类,注入的时候默认的单例的,会报错,实际情况下,一个类型,注入一次就可以了,直接导入的情况下,类必须要有无参构造器
@Import({ Color.class, Red.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class })
@Configuration
public class MyConfig {
@Bean
@Conditional({ WindowsCondition.class })
public Date date() {
return new Date();
}
}
测试就不测试了,很简单,大家自己测