Spring注解开发系列Ⅱ --- 组件注册(下)

1.@Import注册组件

@Import主要功能是通过导入的方式实现把实例加入springIOC容器中,

/**
* 给容器注册组件
* 1.包扫描+组件标注注解(@Controller,@Service,@Repository,@Component)
* 2.@Bean(导入第三方包里的组件)
* 3.@Import[快速给容器导入组件]
* 1)@Import(要导入容器的组件),容器中就会自动注册这个组件
* 2)ImportSelector:返回需要导入的组件的全类名数组
* 3)ImportBeanDefinitionRegistrar:
* 4.使用Spring提供的FactoryBean注册组件:
* 1)默认获取到的是工厂bean调用getObject创建的对象
* 2)获取工厂bean本身需要在bean的id前加"&"
*/

@Import({/*Color.class,*/Red.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})
@Configuration
public class ImportConfig {
@Bean
public ColorFactoryBean colorFactoryBean(){
return new ColorFactoryBean();
}
}

使用ImportSelector注册组件:

public class MyImportSelector implements ImportSelector {
    /**
     * 返回值,导入到容器中组件的全类名
     * AnnotationMetadata:当前标注@Import注解的类的所有注解信息
     * @param annotationMetadata
     * @return
     */
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {

        return new String[]{"com.wang.bean.Blue"};
    }
} 

InportBeanDefinitionRegistrar:手动注册组件

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    /**
     *
     * @param annotationMetadata 当前类的注解信息
     * @param beanDefinitionRegistry BeanDefinition注册类
     *                               把所有需要添加到容器中的Bean,返回需要导入的组件
     *
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
        boolean red  = beanDefinitionRegistry.containsBeanDefinition("com.wang.bean.Red");
        boolean blue = beanDefinitionRegistry.containsBeanDefinition("com.wang.bean.Blue");

        if (blue && red){  //如果容器中有该组件,注册一个
            RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Yellow.class);
            beanDefinitionRegistry.registerBeanDefinition("yellow",rootBeanDefinition);
        }
    }
}

测试:

@Test
    public void testImport(){
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(ImportConfig.class);
        String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
        for (String name:beanDefinitionNames){
            System.out.println(name);
        }

    }

 

2.使用FactoryBean注册组件:

关于FactoryBean和BeanFactory

首先创建一个类实现FactoryBean<T>接口,其中T是要注册的Bean的类型:

public class ColorFactoryBean implements FactoryBean<Color> {

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

    @Override
    public Class<?> getObjectType() {
        return Color.class;
    }
    //是否单例

    /**
     * true 单例
     * false 多例
     * @return
     */
    @Override
    public boolean isSingleton() {
        return false;
    }
}

在config配置类中注册这个FactoryBean:

@Configuration
public class ImportConfig {
    @Bean
    public ColorFactoryBean colorFactoryBean(){
        return new ColorFactoryBean();
    }
}

测试:

 @Test
    public void testBeanFactory(){
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(ImportConfig.class);

        //工厂bean调用的是getObject取得的对象
        Color colorFactoryBean = (Color) annotationConfigApplicationContext.getBean("colorFactoryBean");
        Color colorFactoryBean2 = (Color) annotationConfigApplicationContext.getBean("colorFactoryBean");
        System.out.println("bean的类型:"+colorFactoryBean.getClass());

        System.out.println(colorFactoryBean==colorFactoryBean2);

        //获取ColorFactoryBean
        Object bean = annotationConfigApplicationContext.getBean("&colorFactoryBean");
        System.out.println("bean的类型:"+bean.getClass());
    }

 

posted @ 2018-12-11 15:59  薛定谔病态猫  阅读(298)  评论(0编辑  收藏  举报