目录
1、ConfigurationClassPostProcessor
4.2 ImportBeanDefinitionRegistrar
@Import:用来向ioc容器注册组件。
注意:@Import只是向容器注册添加组件的相关信息,组件还未实例化,后续由容器进行实例化。
value数组值:
普通组件类、实现ImportSelector接口的实现类、实现ImportBeanDefinitionRegistrar接口的实现类

1、普通组件类:直接向容器注册组件,组件的id为组件的全限定类名,若是组件是一个配置类,则配置类内的组件(若配置类定义了内部类,也会扫描内部类判断是否加载该内部类)也会被注册到容器中
2、实现ImportSelector接口的实现类:通过实现selectImports方法返回组件的全限定类名数组,组件的id为组件的全限定类名
- public class MyImportSelector implements ImportSelector {
- /**
- *
- * @param importingClassMetadata 当前标识Import注解的类的所有注解信息
- * @return 返回组件的全类名
- */
- @Override
- public String[] selectImports(AnnotationMetadata importingClassMetadata) {
- return new String[]{"com.mzp.component.service.Red"};
- }
- }
3、实现ImportBeanDefinitionRegistrar接口的实现类:通过实现registerBeanDefinitions方法,可自定义向容器注册组件,可指定组件id
- public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
- /**
- *
- * @param importingClassMetadata 标识Import注解的类的所有注解信息
- * @param registry Bean定义的注册类
- */
- @Override
- public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
- RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(RainRow.class);
- registry.registerBeanDefinition("rain",rootBeanDefinition);
- }
- }
用来解析标识@Configuration配置类。
创建ioc容器时将ConfigurationClassPostProcessor注册到容器中,这是一个BeanDefinitionRegistryPostProcessor实现类,在refresh方法中运行invokeBeanDefinitionRegistryPostProcessors方法时,调用ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法里的processConfigBeanDefinitions方法去解析容器已注册的标识@Configuration的配置类

processConfigBeanDefinitions方法创建ConfigurationClassParser对象去解析@Configuration配置类的信息,包括解析注解@Import信息

在parse方法中调用processConfigurationClass方法

processConfigurationClass方法通过循环调用doProcessConfigurationClass方法来解析当前配置类和配置类的父类信息

doProcessConfigurationClass方法解析多个spring注解,例如
@PropertySource、@ComponentScan、@Import、@ImportResource、@Bean、解析内部类信息等
解析内部类
定位到如图processImports方法,该方法就是实际用来解析@Import注解

getImports方法返回所有@Import注解的value集合,getImports方法通过collectImports方法获取当前组件标识@Import的value集合,包括元注解内部的@Import的value集合

在processImports方法中遍历已得到@Import的value集合importCandidates,判断每个value属于哪种类型
若是value实现了ImportSelector接口,则先通过容器工具类创建对象,然后调用对象的selectImports方法得到导入组件数组importClassNames,继续递归调用processImports方法解析每个导入组件

若是value实现了ImportBeanDefinitionRegistrar接口, 创建该对象,将对象添加到当前类的importBeanDefinitionRegistrars集合中

在后续解析完所有的@Configuration配置类后,调用ConfigurationClassPostProcessor的loadBeanDefinitions方法注册每个配置组件类到容器时,

调用loadBeanDefinitionsForConfigurationClass方法的loadBeanDefinitionsFromRegistrars方法运行当前类的importBeanDefinitionRegistrars集合的registerBeanDefinitions方法


当前value都没实现ImportSelector、ImportBeanDefinitionRegistrar接口时,将它当成一个配置类继续调用processConfigurationClass方法解析该配置类

- @Test
- public void test15(){
- ApplicationContext applicationContext = new AnnotationConfigApplicationContext(ImportConfig.class);
-
- }
- package com.mzp.component.myimport;
-
- import com.mzp.component.service.RainRow;
- import org.springframework.beans.factory.support.BeanDefinitionRegistry;
- import org.springframework.beans.factory.support.RootBeanDefinition;
- import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
- import org.springframework.core.type.AnnotationMetadata;
-
- public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
- /**
- *
- * @param importingClassMetadata 标识Import注解的类的所有注解信息
- * @param registry Bean定义的注册类
- */
- @Override
- public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
- RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(RainRow.class);
- registry.registerBeanDefinition("rain",rootBeanDefinition);
- }
- }
- package com.mzp.component.myimport;
-
- import org.springframework.context.annotation.ImportSelector;
- import org.springframework.core.type.AnnotationMetadata;
-
-
- public class MyImportSelector implements ImportSelector {
- /**
- *
- * @param importingClassMetadata 当前标识Import注解的类的所有注解信息
- * @return 返回组件的全类名
- */
- @Override
- public String[] selectImports(AnnotationMetadata importingClassMetadata) {
- return new String[]{"com.mzp.component.service.Red"};
- }
- }
- package com.mzp.component.myimport;
-
- public class Test {
- public Test(){
- System.out.println("Test()");
- }
- }
- package com.mzp.component.config;
-
- import com.mzp.component.myimport.MyImportBeanDefinitionRegistrar;
- import com.mzp.component.myimport.MyImportSelector;
- import com.mzp.component.myimport.Test;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.context.annotation.Import;
-
- @Configuration
- @Import(value = {Test.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
- public class ImportConfig {
-
- }