@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();
}
}
測試就不測試了,很簡單,大家自己測