天天看点

【八】Spring源码分析之扫描注册Bean----ConfigurationClassPostProcessor的processConfigBeanDefinitions方法一、简介二、源码三、checkConfigurationClassCandidate方法四、parser.parse() 五、this.reader.loadBeanDefinitions()

一、简介

该后置处理器是扫描、解析、注册所有配置类的Bean

入口

【八】Spring源码分析之扫描注册Bean----ConfigurationClassPostProcessor的processConfigBeanDefinitions方法一、简介二、源码三、checkConfigurationClassCandidate方法四、parser.parse() 五、this.reader.loadBeanDefinitions()

 扫描、解析、注册所有配置类bean的流程图:

【八】Spring源码分析之扫描注册Bean----ConfigurationClassPostProcessor的processConfigBeanDefinitions方法一、简介二、源码三、checkConfigurationClassCandidate方法四、parser.parse() 五、this.reader.loadBeanDefinitions()

二、源码

ConfigurationClassPostProcessor类processConfigBeanDefinitions方法

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
		List<BeanDefinitionHolder> configCandidates = new ArrayList<BeanDefinitionHolder>();
        //  获取BeanFactory中的beanDefinitionNames,我debug时有8个。
		String[] candidateNames = registry.getBeanDefinitionNames();

		for (String beanName : candidateNames) {
			BeanDefinition beanDef = registry.getBeanDefinition(beanName);
			if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
					ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
				if (logger.isDebugEnabled()) {
					logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
				}
			}

            // 判断该bean是否为配置类
			else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {

                // 我debug的时候最终加到配置类候选的只有启动类
				configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
			}
		}

		// Return immediately if no @Configuration classes were found
		if (configCandidates.isEmpty()) {
			return;
		}

		// Sort by previously determined @Order value, if applicable

        // 对configCandidates 进行 排序,按照@Order 配置的值进行排序
		Collections.sort(configCandidates, new Comparator<BeanDefinitionHolder>() {
			@Override
			public int compare(BeanDefinitionHolder bd1, BeanDefinitionHolder bd2) {
				int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
				int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
				return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
			}
		});

		// Detect any custom bean name generation strategy supplied through the enclosing application context

        // 检测是否有自定义bean名称生成器

		SingletonBeanRegistry singletonRegistry = null;
		if (registry instanceof SingletonBeanRegistry) {
			singletonRegistry = (SingletonBeanRegistry) registry;
			if (!this.localBeanNameGeneratorSet && singletonRegistry.containsSingleton(CONFIGURATION_BEAN_NAME_GENERATOR)) {
				BeanNameGenerator generator = (BeanNameGenerator) singletonRegistry.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
				this.componentScanBeanNameGenerator = generator;
				this.importBeanNameGenerator = generator;
			}
		}

		// Parse each @Configuration class

        // 解析每一个@Configuration注解修饰的配置类

        // 创建配置类解析器
		ConfigurationClassParser parser = new ConfigurationClassParser(
				this.metadataReaderFactory, this.problemReporter, this.environment,
				this.resourceLoader, this.componentScanBeanNameGenerator, registry);

		Set<BeanDefinitionHolder> candidates = new LinkedHashSet<BeanDefinitionHolder>(configCandidates);
		Set<ConfigurationClass> alreadyParsed = new HashSet<ConfigurationClass>(configCandidates.size());
		do {
			parser.parse(candidates);
			parser.validate();

			Set<ConfigurationClass> configClasses = new LinkedHashSet<ConfigurationClass>(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());
			}

            // 这个方法主要是把前面解析出来的配置类的beanDefinition都注册到容器中
			this.reader.loadBeanDefinitions(configClasses);
			alreadyParsed.addAll(configClasses);

			candidates.clear();
			if (registry.getBeanDefinitionCount() > candidateNames.length) {
				String[] newCandidateNames = registry.getBeanDefinitionNames();
				Set<String> oldCandidateNames = new HashSet<String>(Arrays.asList(candidateNames));
				Set<String> alreadyParsedClasses = new HashSet<String>();
				for (ConfigurationClass configurationClass : alreadyParsed) {
					alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
				}
				for (String candidateName : newCandidateNames) {
					if (!oldCandidateNames.contains(candidateName)) {
						BeanDefinition beanDef = registry.getBeanDefinition(candidateName);
						if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory) &&
								!alreadyParsedClasses.contains(beanDef.getBeanClassName())) {
							candidates.add(new BeanDefinitionHolder(beanDef, candidateName));
						}
					}
				}
				candidateNames = newCandidateNames;
			}
		}
		while (!candidates.isEmpty());

		// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
		if (singletonRegistry != null) {
			if (!singletonRegistry.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
				singletonRegistry.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
			}
		}

		if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
			((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
		}
	}
           

做了4件事:

1.获取BeanFactory中的已注册的beanDefinitionNames,8个,从中找出@Configuration注解修饰的类,我debug的时候只有自己写的启动类进入了候选配置类。如果找不到@Configuration修饰的配置类,则返回。对找到的@Configuration修饰的配置类们进行排序。

这里的candidateNames变量就是Bean工厂中已经有了的beanDefinition的名字,这时有

0 = "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"

1 = "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"

2 = "org.springframework.context.annotation.internalRequiredAnnotationProcessor"

3 = "org.springframework.context.annotation.internalCommonAnnotationProcessor"

4 = "org.springframework.context.event.internalEventListenerProcessor"

5 = "org.springframework.context.event.internalEventListenerFactory"

6 = "app"

7 = "org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory"

configCandidates变量就是@Configuration注解修饰的类,这里只有app

2.检测是否有自定义bean名称生成器

3. 解析每一个@Configuration注解修饰的配置类

4.删除缓存

三、checkConfigurationClassCandidate方法

判断该bean是否为@Configuration修饰的配置类

源码:

public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {

        // 获取类名
		String className = beanDef.getBeanClassName();
		if (className == null) {
			return false;
		}

		AnnotationMetadata metadata;
		if (beanDef instanceof AnnotatedBeanDefinition &&
				className.equals(((AnnotatedBeanDefinition) beanDef).getMetadata().getClassName())) {
			// Can reuse the pre-parsed metadata from the given BeanDefinition...
			metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata();
		}
		else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) {
			// Check already loaded Class if present...
			// since we possibly can't even load the class file for this Class.
			Class<?> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass();
			metadata = new StandardAnnotationMetadata(beanClass, true);
		}
		else {
			try {
				MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className);
				metadata = metadataReader.getAnnotationMetadata();
			}
			catch (IOException ex) {
				if (logger.isDebugEnabled()) {
					logger.debug("Could not find class file for introspecting configuration annotations: " + className, ex);
				}
				return false;
			}
		}

        // 如果存在Configuration 注解,则为BeanDefinition 设置configurationClass属性为full
		if (isFullConfigurationCandidate(metadata)) {
			beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
		}


        // 如果AnnotationMetadata 中有Component,ComponentScan,Import,ImportResource 注解中的任意一个,或者存在 被@bean 注解的方法, 则设置configurationClass属性为lite

		else if (isLiteConfigurationCandidate(metadata)) {
			beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
		}
		else {
			return false;
		}

		// It's a full or lite configuration candidate... Let's determine the order value, if any.
		Map<String, Object> orderAttributes = metadata.getAnnotationAttributes(Order.class.getName());
		if (orderAttributes != null) {
			beanDef.setAttribute(ORDER_ATTRIBUTE, orderAttributes.get(AnnotationUtils.VALUE));
		}

		return true;
	}
           

这里可以看到,判断是否为配置类的标准是,有@Configuration注解 或者@Component 或者@ComponentScan 或者@Import 或者 @ImportResource 或者@Bean

四、parser.parse()

该方法的入口及往后的调用顺序图:

【八】Spring源码分析之扫描注册Bean----ConfigurationClassPostProcessor的processConfigBeanDefinitions方法一、简介二、源码三、checkConfigurationClassCandidate方法四、parser.parse() 五、this.reader.loadBeanDefinitions()

 源码:ConfigurationClassParser类的parse方法

public void parse(Set<BeanDefinitionHolder> configCandidates) {

        // 实例化deferredImportSelectors
		this.deferredImportSelectors = new LinkedList<DeferredImportSelectorHolder>();

        // 遍历配置类,得到BeanDefinition,根据bd类型不同,调用不用的parse方法解析
		for (BeanDefinitionHolder holder : configCandidates) {
			BeanDefinition bd = holder.getBeanDefinition();
			try {

                //debug的时候是自己写的启动类走的这个if
				if (bd instanceof AnnotatedBeanDefinition) {
					parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
				}
				else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
					parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
				}
				else {
					parse(bd.getBeanClassName(), holder.getBeanName());
				}
			}
			catch (BeanDefinitionStoreException ex) {
				throw ex;
			}
			catch (Throwable ex) {
				throw new BeanDefinitionStoreException(
						"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
			}
		}

        // 处理deferredImportSelectors
		processDeferredImportSelectors();
	}
           

做了3件事

1.实例化deferredImportSelectors

2.遍历配置类,得到BeanDefinition,根据bd类型不同,调用不用的parse方法解析

3.处理deferredImportSelectors

这里的parse方法再往下调用会调到ConfigurationClassParser类的processConfigurationClass方法

4.1ConfigurationClassParser类的processConfigurationClass方法

源码:

protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {

        // 是否跳过
		if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
			return;
		}

        // 处理Imported
		ConfigurationClass existingClass = this.configurationClasses.get(configClass);
		if (existingClass != null) {
			if (configClass.isImported()) {
				if (existingClass.isImported()) {
					existingClass.mergeImportedBy(configClass);
				}
				// Otherwise ignore new imported config class; existing non-imported class overrides it.
				return;
			}
			else {
				// Explicit bean definition found, probably replacing an import.
				// Let's remove the old one and go with the new one.
				this.configurationClasses.remove(configClass);
				for (Iterator<ConfigurationClass> it = this.knownSuperclasses.values().iterator(); it.hasNext(); ) {
					if (configClass.equals(it.next())) {
						it.remove();
					}
				}
			}
		}

		// Recursively process the configuration class and its superclass hierarchy.
		SourceClass sourceClass = asSourceClass(configClass);

        // 递归解析
		do {
			sourceClass = doProcessConfigurationClass(configClass, sourceClass);
		}
		while (sourceClass != null);

        // 添加到ConfigurationClassParser的configurationClasses中
		this.configurationClasses.put(configClass, configClass);
	}
           

做了4件事

1.shouldSkip 方法判断是否跳过:

没有被@Conditional注解所修饰,返回false

如果参数中沒有设置条件注解的生效阶段,是配置类的话直接使用PARSE_CONFIGURATION阶段,递归调用shouldSkip,

否则使用REGISTER_BEAN阶段,递归调用shouldSkip 。获取配置类的条件注解得到条件数据,并添加到集合中

遍历conditions,进行判断,如果阶段不满足条件的话,返回true并跳过这个bean的解析

2.判断ConfigurationClassParser的configurationClasses中是否已有该配置类,判断是否需要处理imported

3.递归解析

4.添加到ConfigurationClassParser的configurationClasses中

4.1.1ConfigurationClassParser类的doProcessConfigurationClass方法

源码:

protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
		// Recursively process any member (nested) classes first
        // 处理内部类
		processMemberClasses(configClass, sourceClass);

		// Process any @PropertySource annotations
        // 处理@PropertySource注解
		for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
				sourceClass.getMetadata(), PropertySources.class, org.springframework.context.annotation.PropertySource.class)) {
			if (this.environment instanceof ConfigurableEnvironment) {
				processPropertySource(propertySource);
			}
			else {
				logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
						"]. Reason: Environment must implement ConfigurableEnvironment");
			}
		}

		// Process any @ComponentScan annotations
        // 处理@ComponentScan注解
		Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
				sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
		if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
			for (AnnotationAttributes componentScan : componentScans) {
				// The config class is annotated with @ComponentScan -> perform the scan immediately

                // 扫描
				Set<BeanDefinitionHolder> scannedBeanDefinitions =
						this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
				// Check the set of scanned definitions for any further config classes and parse recursively if necessary

                //遍历扫描到的配置类进行解析
				for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
					if (ConfigurationClassUtils.checkConfigurationClassCandidate(holder.getBeanDefinition(), this.metadataReaderFactory)) {
						parse(holder.getBeanDefinition().getBeanClassName(), holder.getBeanName());
					}
				}
			}
		}

		// Process any @Import annotations
        // 处理@Import注解

		processImports(configClass, sourceClass, getImports(sourceClass), true);

		// Process any @ImportResource annotations.
        // 处理@ImportResource 注解

		if (sourceClass.getMetadata().isAnnotated(ImportResource.class.getName())) {
			AnnotationAttributes importResource =
					AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
			String[] resources = importResource.getStringArray("locations");

            // 遍历配置的locations,加入到configClass 中的ImportedResource
			Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
			for (String resource : resources) {
				String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
				configClass.addImportedResource(resolvedResource, readerClass);
			}
		}

		// Process individual @Bean methods
        // 处理@Bean修饰的方法

		Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);

        // 遍历@Bean注释的方法,添加到configClass
		for (MethodMetadata methodMetadata : beanMethods) {
			configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
		}

		// Process default methods on interfaces

        // 处理接口定义的方法
		processInterfaces(configClass, sourceClass);

		// Process superclass, if any

        // 处理父类
		if (sourceClass.getMetadata().hasSuperClass()) {
			String superclass = sourceClass.getMetadata().getSuperClassName();
			if (!superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) {
				this.knownSuperclasses.put(superclass, configClass);
				// Superclass found, return its annotation metadata and recurse
				return sourceClass.getSuperClass();
			}
		}

		// No superclass -> processing is complete
		return null;
	}
           

 做了8件事:

1.处理内部类

2.处理@PropertySource注解

3.处理@ComponentScan注解

4.处理@Import注解

5.处理@ImportResource注解

6.处理@Bean修饰的方法

7.处理接口定义的方法

8.处理父类

举个例子,项目目录:其中App.java有注解@SpringBootApplication,TestConfiguration.java有注解@Configuration,ZipkinController有注解@RestController,TestUser没有注解。

【八】Spring源码分析之扫描注册Bean----ConfigurationClassPostProcessor的processConfigBeanDefinitions方法一、简介二、源码三、checkConfigurationClassCandidate方法四、parser.parse() 五、this.reader.loadBeanDefinitions()

到了这个方法后,进来的是app启动类。

1.app启动类,它会触发处理@ComponentScan注解,扫com.sid包下所有bean找到app、ZipkinController、TestUser、TestConfiguration,再从中找出@Component注解修饰的bean,这里即是(ZipkinController、TestConfiguration),注册这两个@Component注解修饰的Bean。此时,把这两个@Component注解修饰的bean(ZipkinController、TestConfiguration)拿来递归调用ConfigurationClassParser类的parser.parse()方法,解析他们。

2.TestConfiguration,ZipkinController进到这个方法后什么都没触发,注册到容器中。

3.回到上层,继续是app类在这个方法的后续,它会触发处理@Import注解,得到两个处理@Import的类org.springframework.boot.autoconfigure.AutoConfigurationPackages$Registrar

org.springframework.boot.autoconfigure.EnableAutoConfigurationImportSelector

实例化他们并且设置到app类Import相关属性中。

5.结束该方法,结束该方法的上层方法ConfigurationClassParser类的processConfigurationClass方法,回到parser.parse()中继续往下走,进入processDeferredImportSelectors方法

4.2 processDeferredImportSelectors方法

源码:

private void processDeferredImportSelectors() {
		List<DeferredImportSelectorHolder> deferredImports = this.deferredImportSelectors;
		this.deferredImportSelectors = null;
		Collections.sort(deferredImports, DEFERRED_IMPORT_COMPARATOR);

		for (DeferredImportSelectorHolder deferredImport : deferredImports) {
			ConfigurationClass configClass = deferredImport.getConfigurationClass();
			try {

                // getImportSelector得到的是EnableAutoConfigurationImportSelector
                // selectImports调用的是AutoConfigurationImportSelector类的该方法

				String[] imports = deferredImport.getImportSelector().selectImports(configClass.getMetadata());
				processImports(configClass, asSourceClass(configClass), asSourceClasses(imports), false);
			}
			catch (BeanDefinitionStoreException ex) {
				throw ex;
			}
			catch (Throwable ex) {
				throw new BeanDefinitionStoreException("Failed to process import candidates for configuration class [" +
						configClass.getMetadata().getClassName() + "]", ex);
			}
		}
	}
           

 做了2件事:

4.2.1 调用AutoConfigurationImportSelector类的selectImports方法

源码:

public String[] selectImports(AnnotationMetadata annotationMetadata) {
		if (!isEnabled(annotationMetadata)) {
			return NO_IMPORTS;
		}
		try {
			AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
					.loadMetadata(this.beanClassLoader);
			AnnotationAttributes attributes = getAttributes(annotationMetadata);
			List<String> configurations = getCandidateConfigurations(annotationMetadata,
					attributes);
			configurations = removeDuplicates(configurations);
			configurations = sort(configurations, autoConfigurationMetadata);
			Set<String> exclusions = getExclusions(annotationMetadata, attributes);
			checkExcludedClasses(configurations, exclusions);
			configurations.removeAll(exclusions);
			configurations = filter(configurations, autoConfigurationMetadata);
			fireAutoConfigurationImportEvents(configurations, exclusions);
			return configurations.toArray(new String[configurations.size()]);
		}
		catch (IOException ex) {
			throw new IllegalStateException(ex);
		}
	}
           

1 调用AutoConfigurationImportSelector类的selectImports方法,该方法中又调用了getCandidateConfigurations方法。getCandidateConfigurations方法用SpringFactoriesLoader加载了每个引用的包下的spring.factoris文件中定义的类,从中挑选出factoryName=org.springframework.boot.autoconfigure.EnableAutoConfiguration的类

这里加载了这3个spring.factoris文件。其中,只有spring-boot-autoconfigure-1.5.8.RELEASE.jar!/META-INF/spring.factories文件中有factoryName=org.springframework.boot.autoconfigure.EnableAutoConfiguration的类96个。

spring-boot-1.5.8.RELEASE.jar!/META-INF/spring.factories

spring-boot-autoconfigure-1.5.8.RELEASE.jar!/META-INF/spring.factories

spring-beans-4.3.7.RELEASE.jar!/META-INF/spring.factories

2. 回到selectImports方法中,把这96个类,排序,去重,移除不要的。

filter方法从spring.factories中得到factoryName=org.springframework.boot.autoconfigure.AutoConfigurationImportFilter的类,即是org.springframework.boot.autoconfigure.condition.OnClassCondition。用Filter过滤掉96个类中不要的,最后只剩下了 20个类。

3.selectImports方法中fireAutoConfigurationImportEvents方法 ,从spring.factories中得到factoryName=org.springframework.boot.autoconfigure.AutoConfigurationImportListener,即是org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener。使用AutoConfigurationImportEvent事件记录20个类的评测

4.2.2 调用ConfigurationClassParser类的processImports方法

源码:

private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
			Collection<SourceClass> importCandidates, boolean checkForCircularImports) throws IOException {

		if (importCandidates.isEmpty()) {
			return;
		}

		if (checkForCircularImports && isChainedImportOnStack(configClass)) {
			this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
		}
		else {
			this.importStack.push(configClass);
			try {
				for (SourceClass candidate : importCandidates) {
					if (candidate.isAssignable(ImportSelector.class)) {
						// Candidate class is an ImportSelector -> delegate to it to determine imports
						Class<?> candidateClass = candidate.loadClass();
						ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
						ParserStrategyUtils.invokeAwareMethods(
								selector, this.environment, this.resourceLoader, this.registry);
						if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) {
							this.deferredImportSelectors.add(
									new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));
						}
						else {
							String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
							Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
							processImports(configClass, currentSourceClass, importSourceClasses, false);
						}
					}

                    // 如果@Import导入的类实现了ImportBeanDefinitionRegister接口
					else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
						// Candidate class is an ImportBeanDefinitionRegistrar ->
						// delegate to it to register additional bean definitions
						Class<?> candidateClass = candidate.loadClass();

                        //实例化这个@Import导入的类
						ImportBeanDefinitionRegistrar registrar =
								BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);

                        //这个方法里面一直不满足执行逻辑的条件,之后补上
						ParserStrategyUtils.invokeAwareMethods(
								registrar, this.environment, this.resourceLoader, this.registry);
                        
						configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
					}
					else {
						// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
						// process it as an @Configuration class

                        // 这里基本上是走的这个else
						this.importStack.registerImport(
								currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
						processConfigurationClass(candidate.asConfigClass(configClass));
					}
				}
			}
			catch (BeanDefinitionStoreException ex) {
				throw ex;
			}
			catch (Throwable ex) {
				throw new BeanDefinitionStoreException("Failed to process import candidates for configuration class [" +
						configClass.getMetadata().getClassName() + "]", ex);
			}
			finally {
				this.importStack.pop();
			}
		}
	}
           

1.调用ConfigurationClassParser类的processImports方法,处理这20个类。该方法又会去调用processConfigurationClass方法,里面调用doProcessConfigurationClass方法,里面调用doProcessConfigurationClass方法。相当于又把这20个内来拿做了一遍doProcessConfigurationClass方法去处理这20个内中的:内部类、@PropertySource注解、@ComponentScan注解、@Import注解、@ImportResource注解、@Bean修饰的方法、接口定义的方法、父类

 五、this.reader.loadBeanDefinitions()

这里调用的是ConfigurationClassBeanDefinitionReader类的loadBeanDefinitions方法

源码:

public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {

        // 实例化TrackedConditionEvaluator
		TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
		for (ConfigurationClass configClass : configurationModel) {
            // 调用loadBeanDefinitionsForConfigurationClass
			loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
		}
	}
           

loadBeanDefinitionsForConfigurationClass方法源码:

这个方法主要是把前面解析出来的配置类的beanDefinition都注册到容器中

private void loadBeanDefinitionsForConfigurationClass(ConfigurationClass configClass,
			TrackedConditionEvaluator trackedConditionEvaluator) {

        // 使用条件注解判断是否需要跳过这个配置类
		if (trackedConditionEvaluator.shouldSkip(configClass)) {
			String beanName = configClass.getBeanName();

			if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
                // 跳过配置类的话在Spring容器中移除bean的注册
				this.registry.removeBeanDefinition(beanName);
			}
			
            // 从importRegistry 中移除
this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
			return;
		}

		if (configClass.isImported()) {
            // 如果自身是被@Import注释修饰,注册自己
			registerBeanDefinitionForImportedConfigurationClass(configClass);
		}

        // 将@Bean方法注册为bean
		for (BeanMethod beanMethod : configClass.getBeanMethods()) {
			loadBeanDefinitionsForBeanMethod(beanMethod);
		}

        // 将configClass中ImportResource指定的资源注册为bean
		loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
		
        // 如果该类有@Import,且Import进来的类实现了ImportBeanDefinitionRegistrar接口,则调用Import进来的类的registerBeanDefinitions方法。
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
	}
           

做了5件事:

1.使用条件注解判断是否要跳过配置类,如果要跳过配置类的话,在spring中移除该bean的注册,从importRegistry 中移除,返回。

2.如果该bean自身被@Import注释修饰,注册自己。

3.将@Bean方法注册为bean

4.将configClass中中ImportResource指定的资源注册为bean

5.loadBeanDefinitionsFromRegistrars方法,如果该类有@Import,且Import进来的类实现了ImportBeanDefinitionRegistrar接口,则调用Import进来的类的registerBeanDefinitions方法。

AOP相关的AspectJAutoProxyRegistrar类的registerBeanDefinitions方法(注册AnnotationAwareAspectJAutoProxyCreator,设置AOP属性)的调用就是在这里

继续阅读