谈谈Spring的ImportSelector和ImportBeanDefinitionRegistrar

1、@Import

在聊ImportSelector和ImportBeanDefinitioRegistar之前需要先知道@Import。

@Import是写在我们的配置类上的,如下:

@Configuration
@Import({XXX.class,XXX2.class})
public class AppConfig {
}

当Spring扫描我们AppConfig后,就能拿到我们@Import中填的Class,并将其实例化后放到容器当中。

2、@Import中的三种类

@Import中填入的类可以区分为三种:

  • 实现ImportSelector的类
  • 实现ImportBeanDefinitionRegistrar的类
  • 其余的普通类

3、ImportSelector

首先我们看看接口方法:

public interface ImportSelector {

	/**
	 * Select and return the names of which class(es) should be imported based on
	 * the {@link AnnotationMetadata} of the importing @{@link Configuration} class.
	 * @return the class names, or an empty array if none
	 */
	String[] selectImports(AnnotationMetadata importingClassMetadata);

}

这里面要求返回一个String数组,该数组的值为类的全包名,例如:new String[]{"com.dh.AccountService","com.dh.UserService"},那么Spring就会将数组中的类实例化到容器当中。

该方法的参数AnnotationMetadata,此对象为我们@Import所在的类的元信息,例如其他注解,类信息等,在我们的示例代码中,此AnnotationMetadata中可以拿到Configuration注解,Import注解,Class信息,看下图:

这玩意应用场景:可以根据不同的情况来决定注入哪些类,在我们不考虑环境的情况下,可以直接@Bean注入类,也可以直接扫描,而当我们考虑环境的情况下,就有可能某些类并不注入,而且甚至可能需要逻辑代码校验来决定,那么就可以使用这个接口来进行逻辑代码校验并决定是否注入等。

4、ImportBeanDefinitionRegistrar

先看看接口方法

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
	 */
	void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry);

}

这个相比上一个Selector更牛逼,它给了我们一个BeanDefinition的注册器(其实它也是我们的Bean工厂,而我们的Bean工程也是注册器),我们先看看BeanDefinitionRegistry实际上的类型:

而这里的AnnotationMetadata和上面的ImportSelector是一样的。

这玩意的应用场景:

​ 例如Mybatis的代理我们Dao的操作,它需要干的事情是这样的:

​ 1、拿到我们的需要代理的Mapper包并进行扫描

​ 2、生成这些Mappeer的代理实现类,其中包含了它自己的业务规则

​ 3、将生成的Mapper代理实现类存入Spring容器当中去

​ 那么这里我们将Mapper代理实现类存入Spring容器这个步骤就需要我们的ImportBeanDefinitionRegistrar来实现。

​ MyBatis是如何做的呢?

​ 它首先需要一个@MapperScan注解,这个注解里面包含了@Import注解,并导入了它自己ImportBeanDefinitionRegistrar实现类,名字叫MapperScannerRegistrar

,此类当中首先扫描我们MapperScan中value的包,然后循环这些Mapper,完了再创建BeanDefinition,再通过FactoryBean实例化这些Mapper的代理类,并将这些BeanDefinition存入spring容器中,然后Spring容器就会实例化这些代理类。

5、使用ImportBeanDefinitionRegistar模拟一下Mybatis代理Mapper

5.1、自定义注解Select

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface Select {

	public String value() default "";

}

5.2、TestMyFactoryBean

@SuppressWarnings({"rawtypes", "unchecked"})
public class TestMyFactoryBean implements FactoryBean,InvocationHandler {

	@SuppressWarnings({"rawtypes", "unchecked"})
	Class interfaces;

	@SuppressWarnings({"rawtypes", "unchecked"})
	public TestMyFactoryBean(Class interfaces) {
		this.interfaces = interfaces;
	}

	@SuppressWarnings({"rawtypes", "unchecked"})
	@Override
	public Object getObject() throws Exception {
		Class[] classes = new Class[]{interfaces};
		return Proxy.newProxyInstance(this.getClass().getClassLoader(), classes,this);
		//return userDao;
	}

	@SuppressWarnings({"rawtypes", "unchecked"})
	@Override
	public Class getObjectType() {
		return interfaces;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Select select = method.getAnnotation(Select.class);
		if (Objects.nonNull(select)) {
			System.out.println("method : "+method.getName()+"run sql :" + select.value());
		}
		return "this is return value";
	}
}

5.3、UserDao

public interface UserDao {

	@Select("select * from user were id = ?")
	public Object findById();

}

5.4、MyImportBeanDefinitionRegister

public class MyImportBeanDefinitionRegister implements ImportBeanDefinitionRegistrar {
	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		/* 假装这是我们扫描到的Mapper */
		UserDao userDao;
		/* 生成一个FactoryBean,Mybatis对应的 */
		BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(TestMyFactoryBean.class);
		/* 从Builder中拿到BeanDefinition */
		AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
		/* 添加构造器参数 */
		beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(UserDao.class.getName());
		registry.registerBeanDefinition("userDao",beanDefinition);
	}
}

5.5、AppConfig

@Configuration
@Import(MyImportBeanDefinitionRegister.class)
public class AppConfig {
}

5.6、Main1

public class Main1 {

	/**
	 * 测试方法1
	 * */
	public static void test1(){
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
		applicationContext.register(AppConfig.class);
		applicationContext.refresh();
		UserDao userDao = applicationContext.getBean(UserDao.class);
		System.out.println(userDao.findById());
	}
	public static void main(String[] args) {
		test1();
	}
}

这个代码解释:

​ @Select:这个是用来模拟Mybatis的Select注解的,里面只有一个value参数

​ TestMyFactoryBean:这个涉及到Spring中FactoryBean的知识,当我们的类实现FactoryBean这个接口后,那么Spring将不会直接把我们这个类的实例对象当做Bean存入到容器当中,而是将实现的getObject()方法的返回值实例对象当做Bean存入到容器当中去

​ UserDao:模拟我们Mybatis当中的Mapper接口(实际上它就应该是一个Mapper接口)

​ MyImportBeanDefinitionRegister:实现了我们ImportBeanDefinitionRegistar接口的实现类,在这里面我们假装UserDao.class是我们扫描到的,然后生成一个BeanDefinitionBuilder,然后再设置其FactoryBean实现类中构造器的参数,然后再将我们生成的BeanDefinition存入到Spring当中去

​ AppConfig:配置类,其中注意我们@Import中填入了我们的MyImportBeanDefinitionRegister

​ Main1:主类

这里我们可能有疑问,Mybatis是使用MapperScan的,然后在MapperScan中@import了它自己的ImportBeanDefinitionRegistar实现类,而我们这里直接在配置类里面自己@Import了,那么这块需要涉及到自定义扫描我们的注解,这样才能让我们扫描到MapperScan并做后序解析,这块内容是其他方面的知识,后序随笔中会加入这些内容,这里就不对其进行过于的描述,主要是要让大家明白@Import中的三个类,以及其应用场景。

6、源码解析Import的操作在哪

1、我们从底下往上看,首先是我们的Main1中去调用test1,这个是我自己写的Main方法, 不重要:

public class Main1 {
	public static void test1(){
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
		applicationContext.register(AppConfig.class);
		applicationContext.refresh();	// 进入到此方法中
		UserDao userDao = applicationContext.getBean(UserDao.class);
		System.out.println(userDao.findById());
		}

	public static void main(String[] args) {
		test1();
	}
}

2、然后我们看applicationContext中的refresh方法

@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.,准备提前工作,例如设置一些标志位,开始时间等
			prepareRefresh();
			// Tell the subclass to refresh the internal bean factory.,获取BeanFactory
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
			// Prepare the bean factory for use in this context.,做一些Bean的准备工作
			prepareBeanFactory(beanFactory);
			try {
				// Allows post-processing of the bean factory in context subclasses.
				// 空方法
				postProcessBeanFactory(beanFactory);
				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);					//	=================================line1
				// Register bean processors that intercept bean creation.注册BeanPostProcessor
				registerBeanPostProcessors(beanFactory);
				// Initialize message source for this context.
				initMessageSource();
				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();
				// Initialize other special beans in specific context subclasses.
				onRefresh();
				// Check for listener beans and register them.
				registerListeners();
				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);
				// Last step: publish corresponding event.
				finishRefresh();
			}
			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}
				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();
				// Reset 'active' flag.
				cancelRefresh(ex);
				// Propagate exception to caller.
				throw ex;
			}
			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}

此refresh方法中进入到line1方法中,line1这个方法主要是用于执行我们自己定义的BeanFactoryPostProcessor和Spring内置的BeanFactoryPostProcessor,进入看line1下的代码。

3、进入invokeBeanFactoryPostProcessors方法

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());	//	line1
		// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
		// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
		if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}

此方法会进入到line1当中去,在我们的BeanFactoryPostProcessors当中有三种来源:

​ 1、Spring内置的

​ 2、我们手动加入到Spring的

​ 3、我们自定义后被Spring扫描到的

这里的getBeanFactoryPostProcessor是我们自己手动加入到Spring的。

4、进入到invokeBeanFactoryPostProcessors方法中

public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		Set<String> processedBeans = new HashSet<>();

		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			/* 用来存放我们手动添加的BeanFactoryPostProcessor */
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			/* 用来存放我们手动添加的BeanDefinitionRegistryPostProcessor */
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
			/* 此处判断我们手动添加的BeanPostProcessor是否为BeanDefinitionRegistryPostProcessor类型的,如果是,那么则直接执行以下,否则就到后面去执行默认自带的BeanDefinitionRegistryPostProcessor */
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				/* 判断BeanPostProcessor的类型是否为BeanDefinitionRegistryPostProcessor,但注意它的类型一定为BeanFactoryPostProcessor */
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}

			// Do not initialize FactoryBeans here: We need to leave all regular beans
			// uninitialized to let the bean factory post-processors apply to them!
			// Separate between BeanDefinitionRegistryPostProcessors that implement
			// PriorityOrdered, Ordered, and the rest.这个就是一个临时的List用来存放找到的内置的BeanDefinitionRegistryPostProcessor
			/* 用来存放Spring内置的BeanDefinitionRegistryPostProcessor */
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
			// BeanDefinitionRegistry
			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.拿到所有实现BeanDefinitionRegistryPostProcessor接口的BeanFactoryPostProcessor,并放置到currentRegistryProcessors中
			/* 拿到实现了BeanDefinitionRegistryPostProcessor接口的类名的beanName */
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			/* 循环的放到currentRegistryProcessors */
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			/** 对Processor进行排序,该排序规则对象的设置位置为:
			 * org.springframework.context.annotation.AnnotationConfigUtils.registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)
			 * beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
			 * 此时currentRegistryProcessors中存放的时spring内置的,registryProcessors本身放置的是我们自定义的,需要将两个给合并起来
			 */
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			/* 将我们手动加入的BeanDefinitionRegistryPostProcessor和spring内置的合并到一起 */
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);				// line1
			currentRegistryProcessors.clear();/* 清除list */

			................很多代码
	}

这里重点是看line1,至于上面的代码操作我大概解释一下:

​ 首先将我们手动给Spring的BeanFactoryPostProcessor执行,然后哦从容器当中拿实现了BeanDefinitionRegistryPostProcessor(BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子类,做了一个扩展)接口的实现类(注意此时Spring还未扫描包,所以这里能拿出来的就只有内置的),然后将这些内置的BeanDefinitionRegistryPostProcessor排个序,完了再拿去执行,那么执行就是invokeBeanDefinitionRegistryPostProcessors这行代码。

5、进入invokeBeanDefinitionRegistryPostProcessors方法

private static void invokeBeanDefinitionRegistryPostProcessors(
			Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {

		for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
			postProcessor.postProcessBeanDefinitionRegistry(registry);		// line1
		}
	}

这里面的postProcessors是一个数组,因为内置的BeanDefinitionRegistryPostProcessor可能有多个,但当前只一个,名字叫ConfigurationClassPostProcessor,然后我们进入这个类的postProcessBeanDefinitionRegistry方法。

6、ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry

@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
		int registryId = System.identityHashCode(registry);
		if (this.registriesPostProcessed.contains(registryId)) {
			throw new IllegalStateException(
					"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
		}
		if (this.factoriesPostProcessed.contains(registryId)) {
			throw new IllegalStateException(
					"postProcessBeanFactory already called on this post-processor against " + registry);
		}
		this.registriesPostProcessed.add(registryId);

		processConfigBeanDefinitions(registry);	// line1
	}

不关系这些校验,进入到line1当中

7、进入processConfigBeanDefinitions

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
		List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
		String[] candidateNames = registry.getBeanDefinitionNames();/*获取所有BeanDefinition中的Bean的名称*/
		/* 循环所有的类,看是否为配置类,如果是,则需要对这些类进行解析 */
		for (String beanName : candidateNames) {
			BeanDefinition beanDef = registry.getBeanDefinition(beanName);/* 循环拿到所有的BeanDefiniton */
			if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||	/* 判断该类是否已经加载过,如果已经加载过,那么则打一个log */
					ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
				/* 说明此类已经加载过,无需再加载 */
				if (logger.isDebugEnabled()) {
					logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
				}
			}
			/* 如果没加载过,那么判断此类是否是配置类,如果是则加入到configCandidates中后面会对这些配置类进行解析, */
			else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {	/*  */
				configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
			}
		}

		// 如果配置类一个都没有,那就没必要继续往下一步走了
		if (configCandidates.isEmpty()) {
			return;
		}

		// Sort by previously determined @Order value, if applicable,对前面解析出来带有Configration相关的集合排序,此排序值取决于该这些类上面放置的@Order注解
		configCandidates.sort((bd1, bd2) -> {
			int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
			int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
			return Integer.compare(i1, i2);
		});

		// Detect any custom bean name generation strategy supplied through the enclosing application context,如果我们设置了BeanName生成器,那么则使用我们的,否则就使用Spring内置的
		SingletonBeanRegistry sbr = null;
		if (registry instanceof SingletonBeanRegistry) {
			sbr = (SingletonBeanRegistry) registry;
			if (!this.localBeanNameGeneratorSet) {
				BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
				if (generator != null) {
					this.componentScanBeanNameGenerator = generator;
					this.importBeanNameGenerator = generator;
				}
			}
		}

		if (this.environment == null) {
			this.environment = new StandardEnvironment();
		}

		// Parse each @Configuration class
		ConfigurationClassParser parser = new ConfigurationClassParser(
				this.metadataReaderFactory, this.problemReporter, this.environment,
				this.resourceLoader, this.componentScanBeanNameGenerator, registry);

		Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
		Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
		do {/* 解析这些类 */
			parser.parse(candidates);
			parser.validate();

			Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
			configClasses.removeAll(alreadyParsed);

			// Read the model and create bean definitions based on its content
			if (this.reader == null) {
				this.reader = new ConfigurationClassBeanDefinitionReader(
						registry, this.sourceExtractor, this.resourceLoader, this.environment,
						this.importBeanNameGenerator, parser.getImportRegistry());
			}
			this.reader.loadBeanDefinitions(configClasses);					// line1
			..............很多代码
	}

重点看line1,对上面的代码大概描述一下:

​ 1、拿到Spring当中当前所有的Bean的名称

​ 2、循环遍历这些类

​ 2.1、如果当前Bean已经被解析过了,那么不操作,

​ 2..2、如果当前Bean未解析,那么判断其是否为配置类,如果是则加入到集合,不是则不操作。

​ 判断是否为配置类的依据为:是否加入了@Configuration、是否加入了@Import、@Component、@ImportResource、@ComponentScan其中一个,如果加入了@Configuration那么则不会再去判断后面的

​ 3、判断是否存在配置类,不存在则停止

​ 4、对配置类进行排序,排序规则为其@Order注解

​ 5、获取BeanName生成器,如果没配置则会获取默认的

​ 6、创建配置类解析器

​ 7、do...while的解析我们的这些类

​ 8、parser.parse(candidates);解析这些类,

​ 注意这个方法,这里面有我们这次很重要的@Import(这里不解析其他注解例如扫描包,导入xml等),这里面@Import的类我们上面说了三种,除了ImportBeanDefinitionRegistart以外,其他的类都会立即被解析存放Spring到BeanDefinition或调用其ImportSelector的方法,而我们的ImportBeanDefinitionRegistart则会单独的北方知道parser的configutationClasses集合当中。

​ 9、到了我们重点的line1当中,这里面对我们上面解析拿到的ImportBeanDefinitionRegistart实现类单独的拿去执行

8、进入到this.reader.loadBeanDefinitions(configClasses);

public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
		TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
		for (ConfigurationClass configClass : configurationModel) {
			loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);	// line1
		}
	}

同样我们的ImportBeanDefinitionRegistart实现类可能有多个,这里挨个去执行,而我们本次案例中只有一个,为:MyImportBeanDefinitionRegister,这个类存在的地方在ConfigurationClass的importBeanDefinitionRegistrars属性中:

9、进入到loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);方法中

private void loadBeanDefinitionsForConfigurationClass(
			ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {

		if (trackedConditionEvaluator.shouldSkip(configClass)) {
			String beanName = configClass.getBeanName();
			if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
				this.registry.removeBeanDefinition(beanName);
			}
			this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
			return;
		}

		if (configClass.isImported()) {
			registerBeanDefinitionForImportedConfigurationClass(configClass);
		}
		for (BeanMethod beanMethod : configClass.getBeanMethods()) {
			loadBeanDefinitionsForBeanMethod(beanMethod);
		}

		loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
		loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());				// line1
	}

可以看到line1中就是将我们刚才展示的importBeanDefinitionRegistrars拿出来传给这个方法。

10、进入到loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());

private void loadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) {
		registrars.forEach((registrar, metadata) ->
				registrar.registerBeanDefinitions(metadata, this.registry));				/// line1
	}

这没什么好说的,就是去执行registerBeanDefinitions方法,此时我们看registrar,它就是我们的MyImportBeanDefinitionRegister

11、进入到registrar.registerBeanDefinitions(metadata, this.registry)

此时就到了我们自己定义的ImportBeanDefinitionRegistrar中来,注意这里的importingClassMetadata就是我们前面ConfigurationClass的importBeanDefinitionRegistrars属性的值,而后者registry就是Bean工厂。

本次随笔到此结束,如文有误,深感抱歉,请提出后我改正,感激不尽,

原文地址:https://www.cnblogs.com/daihang2366/p/15080679.html