博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【spring 注解】第4篇:@Import注解
阅读量:6902 次
发布时间:2019-06-27

本文共 5583 字,大约阅读时间需要 18 分钟。

如何给spring容器注入bean

通过前几篇笔记,总结出有如下的已知方式:

  • 包扫描(@ComponentScan)+ 组件使用注解类(@Controller@Service@Repository@Component);
  • 使用@Bean注解;

这篇笔记将记录给容器注入bean的新方式

@Import注解,快速给容器注入Bean

  • 导入单个

配置我们的配置类,假如现在我们要注入一个Color对象,如何使用@Import注解呢?如下代码所示:

@Configuration@Import(Color.class)public class AppConfig3 {    /*给容器中注册一个bean,类型是方法返回值,id就是方法名称*/    @Bean    public Person person() {        return new Person("Kate", 12);    }}

单元测试类:

public void testImport() {        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig3.class);        String[] names = ctx.getBeanDefinitionNames();        for (String name : names) {            System.out.println(name);        }    }

运行结果:注入了Color对象

org.springframework.context.annotation.internalConfigurationAnnotationProcessororg.springframework.context.annotation.internalAutowiredAnnotationProcessororg.springframework.context.annotation.internalRequiredAnnotationProcessororg.springframework.context.annotation.internalCommonAnnotationProcessororg.springframework.context.event.internalEventListenerProcessororg.springframework.context.event.internalEventListenerFactoryappConfig3com.sff.app.bean.Colorperson
  • 导入多个的方式

@Import({Color.class,Person.class})

使用@Import注解时,容器就会自动注册这个类,bean的id默认是全类名;

使用ImportSelector接口

ImprotSelector接口定义如下

package org.springframework.context.annotation;import org.springframework.core.type.AnnotationMetadata;public interface ImportSelector {      String[] selectImports(AnnotationMetadata importingClassMetadata);}

那么如何使用该接口来给容器注册bean呢?当然是要实现该接口了。假如现在要给容器注册Red对象,则进行如下操作:

public class HelloImportSelector implements ImportSelector {    /**     * @param importingClassMetadata 标注@Import注解的类的所有注解信息     * @return 注册到容器的类的全类名     */    @Override    public String[] selectImports(AnnotationMetadata importingClassMetadata) {        return new String[]{"com.sff.app.bean.Red"};    }}

修改配置类即可:

@Configuration@Import({Color.class,Person.class, HelloImportSelector.class})public class AppConfig3 {    /*给容器中注册一个bean,类型是方法返回值,id就是方法名称*/    @Bean    public Person person() {        return new Person("Kate", 12);    }}

使用ImportBeanDefinitionRegistrar接口

该接口的内容如下

package org.springframework.context.annotation;import org.springframework.beans.factory.support.BeanDefinitionRegistry;import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;import org.springframework.core.type.AnnotationMetadata;public interface ImportBeanDefinitionRegistrar {    public void registerBeanDefinitions(            AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry);}

那么现在想给容器注入一个Yellow类对象,操作过程如下

实现ImportBeanDefinitionRegistrar 接口

public class HelloBeanRegistrar implements ImportBeanDefinitionRegistrar{    @Override    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,                                        BeanDefinitionRegistry registry) {        /*判断容器中是否存在 Red 对象*/        boolean red = registry.containsBeanDefinition("com.sff.app.bean.Red");        if(red){            /*定义一个注册对象 Yellow,这里可以知道Yellow的相关信息*/            RootBeanDefinition beanDefinition = new RootBeanDefinition(Yellow.class);            /*注册一个bean*/            registry.registerBeanDefinition("yellow",beanDefinition);        }    }

修改配置类

@Configuration@Import({Color.class,Person.class, HelloImportSelector.class, HelloBeanRegistrar.class})public class AppConfig3 {    /*给容器中注册一个bean,类型是方法返回值,id就是方法名称*/    @Bean    public Person person() {        return new Person("Kate", 12);    }}

使用FactoryBean

还是以给容器注入Color对象进行说明,实现FactoryBean接口

public class ColorFactoryBean implements FactoryBean
{ @Nullable @Override public Color getObject() throws Exception { return new Color(); } @Nullable @Override public Class
getObjectType() { return Color.class; } /*指定是否单例*/ @Override public boolean isSingleton() { return true; }}

配置类中配置ColorFactoryBean对象

@Configuration@Import({Person.class, HelloImportSelector.class, HelloBeanRegistrar.class})public class AppConfig3 {    @Bean    public ColorFactoryBean colorFactoryBean() {        return new ColorFactoryBean();    }}

单元测试

public void testImport() {        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig3.class);        String[] names = ctx.getBeanDefinitionNames();        for (String name : names) {            System.out.println(name);        }        Object colorFactoryBean = ctx.getBean("colorFactoryBean");        System.out.println("获取colorFactoryBean的类型:"+colorFactoryBean.getClass());    }

运行结果如下:

org.springframework.context.annotation.internalConfigurationAnnotationProcessororg.springframework.context.annotation.internalAutowiredAnnotationProcessororg.springframework.context.annotation.internalRequiredAnnotationProcessororg.springframework.context.annotation.internalCommonAnnotationProcessororg.springframework.context.event.internalEventListenerProcessororg.springframework.context.event.internalEventListenerFactoryappConfig3com.sff.app.bean.Personcom.sff.app.bean.RedcolorFactoryBeanpersonyellow获取colorFactoryBean的类型:class com.sff.app.bean.Color

从运行结果发现,在配置类中配置ColorFactoryBean注入到容器中并不是它本身,而是Color对象,那如果要获取ColorFactoryBean本身,使用

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig3.class);Object colorFactoryBean = ctx.getBean("&colorFactoryBean");

就可以了。

总结

如何给容器中注册Bean?

  • 包扫描(@ComponentScan)+ 组件使用注解类(@Controller@Service@Repository@Component);
  • 使用@Bean注解;
  • 使用@Import注解注解;

    • @Import快速注册
    • 实现ImportSelector接口
    • 实现ImportBeanDefinitionRegistrar接口
  • 使用FactoryBean接口;

转载地址:http://irpdl.baihongyu.com/

你可能感兴趣的文章