五Spring中的@Import注解
Posted heliusking
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了五Spring中的@Import注解相关的知识,希望对你有一定的参考价值。
一、使用@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.java
和Yellow.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
就可以看出,,是选择性的导入的意思,所以在这个方法中,我们是可以通过编写不同的逻辑,来返回我们需要导入的组件,那上面自定义的选择导入器,只是为了演示,所以没有具体的条件判断等,可自行扩展,返回需要导入的组件Blue
和Yellow
,然后将这个类加入到@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
ImportBeanDefinitionRegistrar
与ImportSelector
的使用大致相同,它是接口,我们只需实现它,并将它作为参数,放在@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注解的主要内容,如果未能解决你的问题,请参考以下文章