spring注解驱动开发(三):容器注册组件的四种方式

将自定义的bean注册到容器中可以有一下集中方式,第一使用org.springframework.stereotype下的相关注解;第二只用@Bean第三使用@Import;第四类实现FactoryBean接口。

一:自己写的类用@Controller\@Service\@Repository\@Component,结合包扫描

二:使用@Bean注解,将外部类以new的方式注入

三:使用@Import注解

    ①@Import(Xxx.class)直接向容器注册类

    ②实现ImportSelector 接口,自定义将全类名以数据的方式返回

    ③实现ImportBeanDefinitionRegistrar接口,通过registerBeanDefinitions手工来注册bean

四:使用实现FactoryBean接口,getObject方法来注册bean

1 使用Context下org.springframework.stereotype包注解,结合包扫描

    使用@Component、@Controller、@Service、@Repository注解,将所修饰的类注册到spring容器中。

    不是自己写的类,没有加这四种注解,不能注入。该中方式适合自定义的类。

2 使用Context下org.springframework.context.annotation包注解

 

    使用@Bean注解,将外部定义的类以new的方式注入到容器中。

    可以将自定义类,外部类以new的方式添加进容器。

3 使用Import注册组件

3.1 在配置类中使用@Important

@Configuration
@Import(Color.class)
public class MainConfigImport02 {
}

控制台打印容器中的组件

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfigImport02
org.gwsix.ch02.bean.Color

在控制台中输出org.gwsix.ch02.bean.Color,说明color注册到容器中,bean的名字默认是【包名+类名】。

3.2 实现ImportSelector接口,将对应的类注册到bean

    自定义返回值作为组件名导入到容器中。

    1.自定义类实现ImportSelect接口,方法的返回值是要注入到bean的全类名,如果路径不存在,会抛出异常,异常类型是--》org.springframework.beans.factory.BeanDefinitionStoreException:

public class MyImportSelector implements ImportSelector {
    /**
     * importingClassMetadata 当前标注@Import中类中所有bean信息
     * @param importingClassMetadata
     * @return
     */
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{"org.gwsix.ch02.bean.Red","org.gwsix.ch02.bean.Yellow"};
    }
}

    2.在配置类直接导入这个类

@Configuration
@Import({Color.class, MyImportSelector.class})
public class MainConfigImport02 {
}

    3.启动测试类,打印容器中所有bean的名字,在控制台输出会看到Red和Yellow被注入到容器中,容器中对应bean的名字org.gwsix.ch02.bean.Red和org.gwsix.ch02.bean.Yellow

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfigImport02
org.gwsix.ch02.bean.Color
org.gwsix.ch02.bean.Red
org.gwsix.ch02.bean.Yellow

    注意:MyImportSelector并没有被导入到容器中,导入容器的仅仅是selectImports返回值。

3.3 实现ImportBeanDefinitionRegistrar接口,自定义注册bean

     1.自定义类实现ImportBeanDefinitionRegistrar接口

public class MyBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    /**
     * importingClassMetadata:当前类的注解信息和其他信息
     * registry:可以调用相关方法将bean注册和移除bean
     * @param importingClassMetadata
     * @param registry
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        if(registry.containsBeanDefinition("org.gwsix.ch02.bean.Yellow")){
            //指定bean名
            BeanDefinition beanDefinition = new RootBeanDefinition(Blue.class);
            registry.registerBeanDefinition("blue",beanDefinition);
        }
    }
}

    2.将自定义MyBeanDefinitionRegistrar导入到配置文件

@Configuration
@Import({Color.class, MyImportSelector.class, MyBeanDefinitionRegistrar.class})
public class MainConfigImport02 {
}

    3.启动测试类,打印容器中的bean,发现blue注入到容器中

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfigImport02
org.gwsix.ch02.bean.Color
org.gwsix.ch02.bean.Red
org.gwsix.ch02.bean.Yellow
blue

    注意:BeanDefinition beanDefinition = new RootBeanDefinition(Blue.class); 指定注入类的类名

    使用@Import注解可以将【单个类的class直接导入】、【可以在外部自定义类实现ImportSelector接口,selectImports中方法的返回值】、【自定义实现ImportBeanDefinitionRegistrar接口,通过RootBeanDefinition(Blue.class); 指定注入类的类名】

4 使用spring的工厂bean(FactoryBean)

    1.自定义工厂bean实现FactoryBean接口

public class MyFactoryBean implements FactoryBean<Color> {
    //注入的bean
    @Override
    public Color getObject() throws Exception {
        return new Color();
    }
    //类型
    @Override
    public Class<?> getObjectType() {
        return Color.class;
    }
    //是否单例
    @Override
    public boolean isSingleton() {
        return true;
    }
}

    2.在配置类使用@Bean将新建的工厂类注入到容器中

@Configuration
public class MainConfigFactory02 {
    @Bean
    public MyFactoryBean myFactoryBean(){
        return new MyFactoryBean();
    }
}

    3.在测试类中添加方法测试bean是否注入到bean

    //System.out.println(applicationContext.getBean("&myFactoryBean").getClass());
    //获得工厂bean
    @Test
    public  void testFactory(){
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigFactory02.class);
        printBeanName(applicationContext);
        //默认是获得工厂bean创建的对象
        System.out.println(applicationContext.getBean("myFactoryBean").getClass());
        //获得工厂Bean本身,需要在bean名前加入“&”
        //String FACTORY_BEAN_PREFIX = "&";
        System.out.println(applicationContext.getBean("&myFactoryBean").getClass());
    }

    控制台输出以下内容

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfigFactory02
myFactoryBean
class org.gwsix.ch02.bean.Color
class org.gwsix.ch02.bean.MyFactoryBean

    可以发现使用&beanName可以打印出工厂类,在BeanFactory接口中的FACTORY_BEAN_PREFIX定义&BeanName可以获得工厂bean的

以上四种方法,均可以将bean注册到容器中,

第一种:需要配置包扫描

第二种:@Bean

第三种:@Import

第四种:实现BeanFactory

posted @ 2019-03-25 12:47  i孤独行者  阅读(728)  评论(0)    收藏  举报