006Spring注解@Import

1、简介

@Import快速给容器中导入一个组件。

2、基础类

public class Color {}

public class Black {}

public class Blue {}

public class Red {}

public class Yellow {}

3、@Import

3.1、取值

Class<?>[] value();

有三种可以指定:
1、直接写被导入的class
2、ImportSelector
3、ImportBeanDefinitionRegistrar

3.2、作用域

作用到类上。

3.3、讲解

3.3.1、概述

@Import快速给容器中导入一个组件。默认组件id为全类名。

3.3.2、需求一

利用@Import导入Color和Red组件。

3.3.3、配置类

@Configuration
/**
 * @Import 导入组件,id默认是组件的全类名(com.chentongwei.spring.annotation.Import.entity.Color)
 */
@Import({Color.class, Red.class})
public class MainConfig {

    /**
     * 给容器中注册组件:
     * 1)、包扫描+组件标注注解(@ComponentScan)
     * 2)、@Bean【导入的第三方包里面的组件】
     * 3)、@Import【快速给容器中导入一个组件】
     *   3.1)、@Import({要导入容器中的组件})。
     *   3.2)、ImportSelector:返回需要导入的组件的全类名的子数组
     *   3.3)、MyImportBeanDefinitionRegistrar:手工注册bean到容器中
     */

}

3.3.4、测试类

public class ImportTest {

    private final ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);

    @Test
    public void test1() {
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String name : beanDefinitionNames) {
            System.out.println(name);
        }
    }

}

3.3.5、测试结果

mainConfig
com.chentongwei.spring.annotation.Import.entity.Color
com.chentongwei.spring.annotation.Import.entity.Red

PS:

结果分析:

帮我们注入了Color和Red的组件,并且id为全类名。

3.3.6、需求二

如我们还有两个类要导入,我们可以继续往@Import里追加进去,但是很麻烦啊,一坨类,有没有看着清爽点的办法呢?有的,借助ImportSelector接口。

3.3.7、selector

public class MyImportSelector implements ImportSelector {

    /**
     * 自定义逻辑返回需要导入的组件的数组
     *
     * @param importingClassMetadata:当前标注@Import注解的所有注解信息
     * @return: 要导入到容器中的组件的全类名
     */
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[] {"com.chentongwei.spring.annotation.Import.entity.Blue", "com.chentongwei.spring.annotation.Import.entity.Yellow"};
    }
}

PS:

自定义selector需要实现ImportSelector接口并重写selectImports方法。

3.3.8、配置类

@Configuration
/**
 * @Import 导入组件,id默认是组件的全类名(com.chentongwei.spring.annotation.Import.entity.Color)
 */
@Import({Color.class, Red.class, MyImportSelector.class})
public class MainConfig {

    /**
     * 给容器中注册组件:
     * 1)、包扫描+组件标注注解(@ComponentScan)
     * 2)、@Bean【导入的第三方包里面的组件】
     * 3)、@Import【快速给容器中导入一个组件】
     *   3.1)、@Import({要导入容器中的组件})。
     *   3.2)、ImportSelector:返回需要导入的组件的全类名的子数组
     *   3.3)、MyImportBeanDefinitionRegistrar:手工注册bean到容器中
     */

}

3.3.8、测试类

public class ImportTest {

    private final ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);

    @Test
    public void test1() {
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String name : beanDefinitionNames) {
            System.out.println(name);
        }
    }

}

3.3.9、测试结果

mainConfig
com.chentongwei.spring.annotation.Import.entity.Color
com.chentongwei.spring.annotation.Import.entity.Red
com.chentongwei.spring.annotation.Import.entity.Blue
com.chentongwei.spring.annotation.Import.entity.Yellow

PS:

结果分析:

我们可以发现我们只导入了MyImportSelector却自动给我们注入了Blue和Yellow,这样的话就很好了,我们可以单独起一个类来管理需要被导入的组件,不乱。

3.3.10、需求三

我们可能需要做一些判断才能导入bean,比如:我要判断目前的被导入的组件中是否包含Blue和Red,若包含,则导入Black组件,否则不导入Black组件。

3.3.11、registrar

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    /**
     * @param importingClassMetadata:当前类注解信息
     * @param registry:BeanDefinition注册类,把所有需要添加到容器中的bean,调用BeanDefinitionRegistry.registerBeanDefinition手工注册进来
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        boolean red = registry.containsBeanDefinition("com.chentongwei.spring.annotation.Import.entity.Red");
        boolean blue = registry.containsBeanDefinition("com.chentongwei.spring.annotation.Import.entity.Blue");
        if (red && blue) {
            // 指定bean的id以及bean的定义信息
            registry.registerBeanDefinition("black", new RootBeanDefinition(Black.class));
        }
    }
}

PS:

需要实现ImportBeanDefinitionRegistrar的接口并重写registerBeanDefinitions方法。

3.3.12、配置类

@Configuration
/**
 * @Import 导入组件,id默认是组件的全类名(com.chentongwei.spring.annotation.Import.entity.Color)
 */
@Import({Color.class, Red.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class MainConfig {

    /**
     * 给容器中注册组件:
     * 1)、包扫描+组件标注注解(@ComponentScan)
     * 2)、@Bean【导入的第三方包里面的组件】
     * 3)、@Import【快速给容器中导入一个组件】
     *   3.1)、@Import({要导入容器中的组件})。
     *   3.2)、ImportSelector:返回需要导入的组件的全类名的子数组
     *   3.3)、MyImportBeanDefinitionRegistrar:手工注册bean到容器中
     */

}

3.3.13、测试类

public class ImportTest {

    private final ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);

    @Test
    public void test1() {
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String name : beanDefinitionNames) {
            System.out.println(name);
        }
    }

}

3.3.14、测试结果

mainConfig
com.chentongwei.spring.annotation.Import.entity.Color
com.chentongwei.spring.annotation.Import.entity.Red
com.chentongwei.spring.annotation.Import.entity.Blue
com.chentongwei.spring.annotation.Import.entity.Yellow
black

PS:

结果分析:

Black组件自动为我们注入了进来,并且id为自定义的black

3.4、注意

SpringBoot底层大量运用了@Import注解。

4、广告

img
  • 今日头条号:编程界的小学生
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,242评论 19 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 174,362评论 25 709
  • 你来的时候,我没记下你的名字。你走的时候,我却遗憾地忘记问你要地址。 可是这样的时候就是这样,我们便觉得遗憾才是愧...
    Mr_小小寒阅读 218评论 0 0
  • ​他曾经历过一段刻骨铭心的恋情,那恋人在他心里,海枯石烂也不会消失不见。 尽管是她狠心离他而去,却曾经在相爱相处的...
    萱小蕾阅读 302评论 0 0
  • 01 电影界一年一度的盛会“奥斯卡颁奖典礼”马上就要到了。去年此时,几乎是全球影迷都在为小李子能否摘得影帝桂冠操碎...
    清心澜意阅读 270评论 2 3