一、使用@Import注解导入组件

@Import注解的作用是给容器中导入组件,回顾下我们给容器中导入组件的方式,可以通过Spring的xm配置方式,可以通过注解,如@Component等,也可以通过java配置类的方式给容器中导入注解,今天来介绍另一个注解,其作用也是给容器中导入组件。


其用法非常简单,我们举个小例子 ,

配置类MainConfig2

@Configuration
@Import({Color.class,Red.class})//将这两个类导入到容器中
//@Import导入组件,id默认是组件的全类名
public class MainConfig2 { }

其中Color.class和Red.class就是两个非常普通的java类,不必关心这两个类有何特殊的。

我们写个测试方法,用于遍历下容器中bean组件的名字

@Test
public void printBeans(AnnotationConfigApplicationContext applicationContext){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
String[] definitionNames = applicationContext.getBeanDefinitionNames();
for (String name : definitionNames) {
System.out.println(name);
}
}

我们关注下打印的结果:

mainConfig2
com.atguigu.bean.Color //@Import导入组件,id默认是组件的全类名
com.atguigu.bean.Red

二、@Import导入ImportSelector

上面可以看到 ,这种方式进行导入呢?还是略微麻烦了点,如果组件很多,也是比较麻烦的,所以呢,我们也可以结合ImportSelector来使用

首先,我们再写两个类,叫做Bule.javaYellow.java,不必关心类里有什么,哪怕是个空类也是可以的,我们只关心其是否能被正确注入到组件之中

那如何使用ImportSelector呢?

这是一个接口,继承并实现即可。

//自定义逻辑返回需要导入的组件
public class MyImportSelector implements ImportSelector { //返回值,就是到导入到容器中的组件全类名
//AnnotationMetadata:当前标注@Import注解的类的所有注解信息
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
//方法不要返回null值
return new String[]{"com.atguigu.bean.Blue","com.atguigu.bean.Yellow"};
}
}

关于这个导入选择器,从这个方法名selectImports就可以看出,,是选择性的导入的意思,所以在这个方法中,我们是可以通过编写不同的逻辑,来返回我们需要导入的组件,那上面自定义的选择导入器,只是为了演示,所以没有具体的条件判断等,可自行扩展,返回需要导入的组件BlueYellow

,然后将这个类加入到@Import注解的参数中,就像这样

@Configuration
@Import({Color.class,Red.class,MyImportSelector.class})//将这两个类导入到容器中
//@Import导入组件,id默认是组件的全类名
public class MainConfig2 {
}

我们还是用刚才的测试方法打印下结果:

mainConfig2
com.atguigu.bean.Color
com.atguigu.bean.Red
com.atguigu.bean.Blue //Blue被注册进了容器中
com.atguigu.bean.Yellow // Yellow被注册进了容器中

以上就是ImportSelector接口的使用,是比较简单的。

三、@Import导入ImportBeanDefinitionRegistrar

ImportBeanDefinitionRegistrarImportSelector的使用大致相同,它是接口,我们只需实现它,并将它作为参数,放在@Import中即可,。

自定义实现类MyImportBeanDefinitionRegistrar

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

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

在配置类的@Import注解中加入这个自定义的类

@Configuration
@Import({Color.class,Red.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})//将这两个类导入到容器中
//@Import导入组件,id默认是组件的全类名
public class MainConfig2 {
}

依旧使用刚才的测试方法打印一下

mainConfig2
com.atguigu.bean.Color
com.atguigu.bean.Red
com.atguigu.bean.Blue
com.atguigu.bean.Yellow
rainBow // 自定义MyImportBeanDefinitionRegistrar的注册组件

对比后两种注册方法,我们发现,ImportBeanDefinitionRegistrar是没有返回值的,另外它多了一个参数BeanDefinitionRegistry,也就是可以直接在方法中就注册bean。

四、详细分析

我们来看下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 {
/**
* Register bean definitions as necessary based on the given annotation metadata of
* the importing {@code @Configuration} class.
* <p>Note that {@link BeanDefinitionRegistryPostProcessor} types may <em>not</em> be
* registered here, due to lifecycle constraints related to {@code @Configuration}
* class processing.
* @param importingClassMetadata annotation metadata of the importing class
* @param registry current bean definition registry
*/
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry); }

我们看下方法第一个参数AnnotationMetadata importingClassMetadata,这个是注解的元信息,即配置类上所有注解的信息,然后可以在MyImportBeanDefinitionRegistrar自定义我们自己需要的逻辑,动态注册bean、

不同的是,这个类通过BeanDefinitionRegistry本身就可以注册组件。

五、Spring中的@Import注解的更多相关文章

  1. spring 中的@Import注解和@ImportResource注解

    概述:@Import注解是引入带有@Configuration的java类. @ImportResource是引入spring配置文件.xml 案例的核心代码如下: package com.timo. ...

  2. spring框架中的@Import注解

    spring框架中的@Import注解 Spring框架中的@Import注解 在之前的文章中,作者介绍了Spring JavaConfig. 这是除了使用传统的XML文件之外,spring带来的新的 ...

  3. 第5章—构建Spring Web应用程序—关于spring中的validate注解后台校验的解析

    关于spring中的validate注解后台校验的解析 在后台开发过程中,对参数的校验成为开发环境不可缺少的一个环节.比如参数不能为null,email那么必须符合email的格式,如果手动进行if判 ...

  4. Spring 中aop切面注解实现

    spring中aop的注解实现方式简单实例   上篇中我们讲到spring的xml实现,这里我们讲讲使用注解如何实现aop呢.前面已经讲过aop的简单理解了,这里就不在赘述了. 注解方式实现aop我们 ...

  5. Spring中的常用注解

    Spring中的常用注解 1.@Controller 标识一个该类是Spring MVC controller处理器,用来创建处理http请求的对象.

  6. Spring中重要的注解

    现在大部分的Spring项目都会用到注解.使用注解来替换xml,一行简单的注解就可以解决很多事情.但是你真的懂其中的原理吗. 本文翻译于 https://docs.spring.io/spring-f ...

  7. JavaEE开发之Spring中的条件注解组合注解与元注解

    上篇博客我们详细的聊了<JavaEE开发之Spring中的多线程编程以及任务定时器详解>,本篇博客我们就来聊聊条件注解@Conditional以及组合条件.条件注解说简单点就是根据特定的条 ...

  8. spring中aop的注解实现方式简单实例

    上篇中我们讲到spring的xml实现,这里我们讲讲使用注解如何实现aop呢.前面已经讲过aop的简单理解了,这里就不在赘述了. 注解方式实现aop我们主要分为如下几个步骤(自己整理的,有更好的方法的 ...

  9. JavaEE开发之Spring中的条件注解、组合注解与元注解

    上篇博客我们详细的聊了<JavaEE开发之Spring中的多线程编程以及任务定时器详解>,本篇博客我们就来聊聊条件注解@Conditional以及组合条件.条件注解说简单点就是根据特定的条 ...

随机推荐

  1. Mac OS X配置环境变量

    转载注明出处:http://www.jianshu.com/p/7e30b7b7ee48 Mac端环境变量配置 Mac使用bash做为默认的shell MAC OS X环境配置的加载顺序 # 系统级别 ...

  2. 数据库join解释 与视图

    数据库的视图是表运算的结果. 数据库的表是数据单元: join是运算符: 视图是运算结果. 数据库join解释 1.join:将两个表结构连接成一个视图 2.left.right.inner: 从基准 ...

  3. PHP - Filters

    Retrieve the administrator password of this application. 对文件包含的介绍------------第一个链接需要谷歌 https://mediu ...

  4. LeetCode 1197. Minimum Knight Moves

    原题链接在这里:https://leetcode.com/problems/minimum-knight-moves/ 题目: In an infinite chess board with coor ...

  5. CLR调试时的sos.dll/clr.dll/mscorwks.dll/mscordacwks.dll等动态库的版本对应

    大家都知道,在调试托管代码时,一定会加载到sos/clr/mscorwks/mscordacwks这些动态库,才能够很好的完成我们的调试工作,那么他们的版本对应关系是怎样的呢,特别是clr.dll/m ...

  6. cockroachdb docker-compose 本地集群运行以及prometheus监控

    cockroachdb 官方提供的是一个直接使用docker 运行的方式,但是使用docker-compose 会比较方便,可以快速搭建一个集群 同时官方也提供了prometheus 的metrics ...

  7. 8.8poc包问题

    对于8.8的包的问题:zabbix server设备重启后 zabbix server,mariadb,zabbix agent启动不了.是因为在7代的centos中在主机重启后.自动删除了/var/ ...

  8. 新手AS常见问题集锦

    开发环境 以前开发android的时候可以使用eclipse,虽然现在也能使用eclipse,但是google已经不再支持使用eclipse开发android了.因为google有了自己的IDE--- ...

  9. Java动态调用脚本语言Groovy

    Java动态调用脚本语言Groovy 2019-05-15 目录 0. pom.xml添加依赖1. 使用GroovyShell计算表达式2. 使用GroovyScriptEngine脚本引擎加载Gro ...

  10. 冰多多团队-第一次Scrum例会

    冰多多团队-第一次Scrum会议 注:由于对课程要求的不熟悉,所以本文档为周会后的补充总结文档 会议基本情况 会议时间:3.28 19:00 - 19:30 会议地点:新主楼F座2楼沙发休息处 工作情 ...