一.概述
1.往容器中注入BeanDefinition,@Import相对直接一点,将class转换成BeanDefinition对象,@ImportResource通过配置文件绕了一层(即读取文件,解析里面配置属性,找到class,再转换成BeanDefinition对象)
2.@Import导入类,@ImportResource导入xml配置文件;导入类能做的事情,导入配置文件xml更可以(注:@Import经常用于导入第三方包的单个类 ,@Bean/@ImportResource也可以)
3.例子@Import({ XXXConfiguration.class, XXXImportSelector.class, XXXImportBeanDefinitionRegistrar.class, XXX@component.class})//支持四种类型 @ImportResource({ "classpath*:XX.xml" }),导入xml配置文件
二.原理:
1.BeanFactoryPostProcessor>>BeanDefinitionRegistryPostProcessor>>spring容器实例化的时候创建后置处理器BeanDefinitionRegistryPostProcessor
2.容器refresh刷新的时候,统一执行BeanFactory后置处理器
3.根据主配置类(容器启动就注入的@Configuration启动类)信息,判断主配置为是full模式还是lite模式,解析成configurationClasses放入集合中
4.根据主配置类,扫描class(默认和主配置类同级包路径),解析class上注解
1).如果是XXConfiguration.class类,解析成configurationClasses放入集合中(注:XXConfiguration.class配置类中可能还有注解@Import或者@ImportResource注解,所以要递归)
2).如果是XXImportSelector.class类,实现ImportSelector接口,会调用执行对应的接口方法selectImports,返回要注入的所有类全名称(注:这个就是springboot自动装配的原理,所有类全名称通过spi的方式取的,也就是META-INF/spring.factories文件读取),解析成configurationClasses放入集合中,同样可能存在嵌套注解,所以也要递归处理
3).如果是XXImportBeanDefinitionRegistrar.class,ImportBeanDefinitionRegistrar接口方法自定义BeanDefinition对象,注册进容器;其实和ImportSelector接口类似,ImportSelector接口借助外面获取class信息,解析成configurationClasses,然后封装成BeanDefinition对象,注册进容器;ImportBeanDefinitionRegistrar接口方法,直接自定义BeanDefinition对象,注册进容器,一步到位
4).如果是XX@component.class类,也即普通的注解组件类(service/controller等),直接解析成BeanDefinition对象,注册进容器中,一步到位
5.循环configurationClasses集合,组装成BeanDefinition对象,注册进容器