容器导入bean的方式

-1 自己写的类(@component...)
-2 第三方jar(@Bean)的方式
-3 @import({xxx.class,yyy.class}) beanId默认是组件的全类名

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

}

-4 @importSelector: 返回需要导入的组件的全类名数组

自定义selector组件
//自定义逻辑返回需要导入的组件
public class MyImportSelector implements ImportSelector {

    //返回值,就是到导入到容器中的组件全类名
    //AnnotationMetadata:当前标注@Import注解的类的所有注解信息
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        //importingClassMetadata
        //方法不要返回null值,会有npe问题
        return new String[]{"xxx.xxx.xxx","xxx.xxx.xxx"};
    }

}

-5 @importBeanDefinitionRegister:可以自定义直接向容器中注册Bean

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    /**
     * AnnotationMetadata:当前类的注解信息
     * BeanDefinitionRegistry:BeanDefinition注册类;
     *         把所有需要添加到容器中的bean;调用
     *         BeanDefinitionRegistry.registerBeanDefinition手工注册进来
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        
        
        //指定Bean定义信息;(Bean的类型,Bean的socpe等。。。)
        RootBeanDefinition beanDefinition = new  RootBeanDefinition(RainBow.class);
        //注册一个Bean,指定bean名
        registry.registerBeanDefinition("rainBow", beanDefinition);
    }

}

==
++使用@import的demo++==

@Import({Color.class,Red.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})

-6 使用 Spring 提供的 FactoryBean (工厂Bean)

//创建一个Spring定义的FactoryBean
public class ColorFactoryBean implements FactoryBean<Color> {

    //返回一个Color对象,这个对象会添加到容器中
    @Override
    public Color getObject() throws Exception {
        System.out.println("ColorFactoryBean...getObject...");
        return new Color();
    }

    @Override
    public Class<?> getObjectType() {
        return Color.class;
    }

    //是单例?
    //true:这个bean是单实例,在容器中保存一份
    //false:多实例,每次获取都会创建一个新的bean;
    @Override
    public boolean isSingleton() {
        return false;
    }

}

之后将这个 factoryBean 注册到容器中,
getBean("id")实际上是 factoryBean 的 getObject() 生产的 Bean
getBean("&id")获取工厂类本身
@Bean
public ColorFactoryBean colorFactoryBean(){
    return new ColorFactoryBean();
}

摸鱼市民王月半
1 声望0 粉丝