天天看點

spring注解 @Import的使用,ImportSelector接口,ImportBeanDefinitionRegistrar接口

@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();
    }
}
           

測試就不測試了,很簡單,大家自己測