spring 中包自动扫描之 ConfigurationClassPostProcessor

在前文 spring 中包自动扫描之 component-scan 解析 一文中我们知道,待扫描结束后,注册了一堆注解模式下相关的后置处理器,其中一个就是 ConfigurationClassPostProcessor,从类名猜测主要是针对配置类的,下面我们就来看看这个类到底是什么,以及在 spring 中的作用是什么。

实例化

先来看下这个类的结构图。
ConfigurationClassPostProcessor 类结构图
从图中可知,这是一个 BeanFactoryPostProcessor,在 AbstractApplicationContext#refresh 中,当 beanFactory 初始化完成之后,会调用 AbstractApplicationContext#invokeBeanFactoryPostProcessors。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
}
public static void invokeBeanFactoryPostProcessors(
		ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

	Set<String> processedBeans = new HashSet<>();

	if (beanFactory instanceof BeanDefinitionRegistry) {
		BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
		List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
		List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

		for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
			// 处理参数 beanFactoryPostProcessors 
		}

		List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

		// 首先,调用实现了 PriorityOrdered 的 BeanDefinitionRegistryPostProcessor
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
				processedBeans.add(ppName);
			}
		}
		sortPostProcessors(currentRegistryProcessors, beanFactory);
		registryProcessors.addAll(currentRegistryProcessors);
		invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
		currentRegistryProcessors.clear();

		// 接着,调用实现了 Ordered 的 BeanDefinitionRegistryPostProcessor
		...

		// 最后,调用剩下的 BeanDefinitionRegistryPostProcessor
		...

		// 调用 postProcessBeanFactory 回调
		invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
	}

	else {
		// Invoke factory processors registered with the context instance.
		invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
	}

	// 处理 BeanFactoryPostProcessor
	...

	beanFactory.clearMetadataCache();
}

ConfigurationClassPostProcessor 既实现了 BeanDefinitionRegistryPostProcessor,又实现了 PriorityOrdered,所以会被第一个处理,调用 beanFactory.getBean 进行实例对象的创建获取。
有一点需要注意,就是实例化完成,进行初始化时,在 AbstractAutowireCapableBeanFactory#initializeBean 中调用 invokeAwareMethods,此时由于实现了 BeanClassLoaderAware 接口,会执行 setBeanClassLoader。

// initializeBean --> invokeAwareMethods
@Override
public void setBeanClassLoader(ClassLoader beanClassLoader) {
	this.beanClassLoader = beanClassLoader;
	if (!this.setMetadataReaderFactoryCalled) {
		// 赋值
		this.metadataReaderFactory = new CachingMetadataReaderFactory(beanClassLoader);
	}
}
public CachingMetadataReaderFactory(@Nullable ClassLoader classLoader) {
	super(classLoader);
	setCacheLimit(DEFAULT_CACHE_LIMIT);
}
// CachingMetadataReaderFactory 父类
public SimpleMetadataReaderFactory(@Nullable ClassLoader classLoader) {
	this.resourceLoader =
			(classLoader != null ? new DefaultResourceLoader(classLoader) : new DefaultResourceLoader());
}

可以看到对 ConfigurationClassPostProcessor 中 metadataReaderFactory 进行了赋值,并对 CachingMetadataReaderFactory 父类 SimpleMetadataReaderFactory 中 resourceLoader 也进行了赋值。
接着,由于前面注册了 ApplicationContextAwareProcessor 的缘故,会调用 ApplicationContextAwareProcessor#postProcessBeforeInitialization,在其中执行 invokeAwareInterfaces,会执行 setEnvironemnt 和 setResourceLoader。
执行 setResourceLoader 时会将当前 ApplicationContext 作为 ResourceLoader 传入。

@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
	Assert.notNull(resourceLoader, "ResourceLoader must not be null");
	this.resourceLoader = resourceLoader;
	if (!this.setMetadataReaderFactoryCalled) {
		// 赋值
		this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);
	}
}
public CachingMetadataReaderFactory(@Nullable ResourceLoader resourceLoader) {
	super(resourceLoader);
	if (resourceLoader instanceof DefaultResourceLoader) {
		// 赋值
		this.metadataReaderCache =
				((DefaultResourceLoader) resourceLoader).getResourceCache(MetadataReader.class);
	}
	else {
		setCacheLimit(DEFAULT_CACHE_LIMIT);
	}
}

对之前 invokeAwareMethods 中 调用 setBeanClassLoader 时赋值的 metadataReaderFactory 和 resourceLoader 都进行了覆盖,并且对 CachingMetadataReaderFactory 中 metadataReaderCache 进行了赋值。

// DefaultResourceLoader
public <T> Map<Resource, T> getResourceCache(Class<T> valueType) {
	return (Map<Resource, T>) this.resourceCaches.computeIfAbsent(valueType, key -> new ConcurrentHashMap<>());
}

所以,同一个 AbstractApplicationContext 下,共用同一个 DefaultResourceLoader,由于在包的扫描时访问过包下的字节码文件,resourceCaches 中 key 为 MetadataReader.class,所以此时返回给 metadataReaderCache 赋值的 ConcurrentHashMap 包含之前访问到的资源和 MetadataReader 对象。
这样,就完成了 ConfigurationClassPostProcessor 的实例化。
顺便说下,目前在 spring 中,BeanDefinitionRegistryPostProcessor 的实现类只有 ConfigurationClassPostProcessor 一个。

配置类的处理 invokeBeanDefinitionRegistryPostProcessors

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

	for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
		StartupStep postProcessBeanDefRegistry = applicationStartup.start("spring.context.beandef-registry.post-process")
				.tag("postProcessor", postProcessor::toString);
		postProcessor.postProcessBeanDefinitionRegistry(registry);
		postProcessBeanDefRegistry.end();
	}
}

@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
	int registryId = System.identityHashCode(registry);
	if (this.registriesPostProcessed.contains(registryId)) {
		throw ...
	}
	if (this.factoriesPostProcessed.contains(registryId)) {
		throw ...
	}
	this.registriesPostProcessed.add(registryId);

	processConfigBeanDefinitions(registry);
}

针对每一个 BenDefinitionRegistry,即 BeanFactory,生成一个 registryId,用来表示只执行一次。
下面来看看 processConfigBeanDefinitions 具体做了什么。

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
	List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
	String[] candidateNames = registry.getBeanDefinitionNames();

	// 遍历注册的 BeanDefinition 名称
	for (String beanName : candidateNames) {
		BeanDefinition beanDef = registry.getBeanDefinition(beanName);
		// 
		if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
			...
		}
		else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
			configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
		}
	}

	// 没有找到 @Configuration 修饰的类,立即返回
	if (configCandidates.isEmpty()) {
		return;
	}

	// 根据 @Order 排序
	configCandidates.sort((bd1, bd2) -> {
		int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
		int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
		return Integer.compare(i1, i2);
	});

	// 检查是否存在 bean 名称生成策略
	SingletonBeanRegistry sbr = null;
	if (registry instanceof SingletonBeanRegistry) {
		sbr = (SingletonBeanRegistry) registry;
		if (!this.localBeanNameGeneratorSet) {
			BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
					AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
			// null
			if (generator != null) {
				this.componentScanBeanNameGenerator = generator;
				this.importBeanNameGenerator = generator;
			}
		}
	}

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

	// 解析每一个配置类,先创建一个解析器
	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 {
		StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
		parser.parse(candidates);
		parser.validate();

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

		// 基于配置类内容,创建 BeanDefinition,并完成注册
		if (this.reader == null) {
			this.reader = new ConfigurationClassBeanDefinitionReader(
					registry, this.sourceExtractor, this.resourceLoader, this.environment,
					this.importBeanNameGenerator, parser.getImportRegistry());
		}
		this.reader.loadBeanDefinitions(configClasses);
		alreadyParsed.addAll(configClasses);
		processConfig.tag("classCount", () -> String.valueOf(configClasses.size())).end();

		candidates.clear();
		if (registry.getBeanDefinitionCount() > candidateNames.length) {
			String[] newCandidateNames = registry.getBeanDefinitionNames();
			Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
			Set<String> alreadyParsedClasses = new HashSet<>();
			for (ConfigurationClass configurationClass : alreadyParsed) {
				alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
			}
			// 遍历新的候选名称,找出新注册的 beanDefinition,判断是否是配置类,是配置类,且未被处理,将再次加入 candidates,开启下一次循环
			for (String candidateName : newCandidateNames) {
				if (!oldCandidateNames.contains(candidateName)) {
					BeanDefinition bd = registry.getBeanDefinition(candidateName);
					if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
							!alreadyParsedClasses.contains(bd.getBeanClassName())) {
						candidates.add(new BeanDefinitionHolder(bd, candidateName));
					}
				}
			}
			candidateNames = newCandidateNames;
		}
	}
	while (!candidates.isEmpty());

	// // 注册 ImportRegistry 作为一个单例对象,为了支持ImportAware @Configuration类
	if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
		sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
	}

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

先遍历注册的 BeanDefintion 名称,检查是否是配置类,是,加入 configCandidates 候选集合。

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

	String className = beanDef.getBeanClassName();
	if (className == null || beanDef.getFactoryMethodName() != null) {
		return false;
	}

	AnnotationMetadata metadata;
	if (beanDef instanceof AnnotatedBeanDefinition &&
			className.equals(((AnnotatedBeanDefinition) beanDef).getMetadata().getClassName())) {
		
		metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata();
	}
	else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) {
		// 检查已经加载的 Class
		Class<?> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass();
		if (BeanFactoryPostProcessor.class.isAssignableFrom(beanClass) ||
				BeanPostProcessor.class.isAssignableFrom(beanClass) ||
				AopInfrastructureBean.class.isAssignableFrom(beanClass) ||
				EventListenerFactory.class.isAssignableFrom(beanClass)) {
			return false;
		}
		metadata = AnnotationMetadata.introspect(beanClass);
	}
	else {
		try {
			MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className);
			metadata = metadataReader.getAnnotationMetadata();
		}
		catch (IOException ex) {
			return false;
		}
	}
	
	// 判断是否持有 @Configuration 注解,如果持有获取其注解属性
	Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
	// 控制是否对配置类进行增强
	if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
		beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
	}
	else if (config != null || isConfigurationCandidate(metadata)) {
		beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
	}
	else {
		return false;
	}

	// 是配置类,获取 @Order 属性
	Integer order = getOrder(metadata);
	if (order != null) {
		beanDef.setAttribute(ORDER_ATTRIBUTE, order);
	}

	return true;
}

public static boolean isConfigurationCandidate(AnnotationMetadata metadata) {
	// 不考虑接口
	if (metadata.isInterface()) {
		return false;
	}

	// 持有这四个中一个 @Component/@ComponentScan/@Import/@ImportResource
	for (String indicator : candidateIndicators) {
		if (metadata.isAnnotated(indicator)) {
			return true;
		}
	}

	// 最后,查找 @Bean 方法
	return hasBeanMethods(metadata);
}

先判断是否直接持有 @Configuration,没有,再调用 isConfigurationCandidate 进行判断。是接口直接返回 false,否则判断是否持有 @Component、@ComponentScan、@Import、@ImportResource 四个注解中的一个,如果都不存在,最后检查类中是否存在 @Bean 修饰的方法,存在,即视为配置类。
接着,是配置类,获取 @Order 注解属性。

// 获取 @Order 注解属性
@Nullable
public static Integer getOrder(AnnotationMetadata metadata) {
	Map<String, Object> orderAttributes = metadata.getAnnotationAttributes(Order.class.getName());
	return (orderAttributes != null ? ((Integer) orderAttributes.get(AnnotationUtils.VALUE)) : null);
}

接着利用 @Order 属性值对 configCandidates 排序后,进行配置类的解析。先创建一个解析器,ConfigurationClassParser,接着调用 parse 方法,传入 configCandidates 进行解析。

// 配置类解析
public void parse(Set<BeanDefinitionHolder> configCandidates) {
	// 遍历注册的配置类
	for (BeanDefinitionHolder holder : configCandidates) {
		BeanDefinition bd = holder.getBeanDefinition();
		try {
			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 ...
		}
		catch (Throwable ex) {
			throw ...
		}
	}

	this.deferredImportSelectorHandler.process();
}

根据不同的 BeanDefinition 类型,执行不同的解析策略。不管是哪一种策略,都是先封装成一个 ConfigurationClass 对象,然后调用 ConfigurationClassParser#processConfigurationClass 进行处理。

protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
	processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
}

protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
	// 判断是否持有 @Conditional,不持有不跳过
	if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
		return;
	}

	// 判断当前处理类是否已经存在
	ConfigurationClass existingClass = this.configurationClasses.get(configClass);
	if (existingClass != null) {
		if (configClass.isImported()) {
			// 两者都是 imported,合并即可,existingClass 为 non-imported,则不处理,之后直接返回
			if (existingClass.isImported()) {
				existingClass.mergeImportedBy(configClass);
			}
			return;
		}
		else {
			// configClass 是 non-imported,对 configurationClasses 中的 existingClass 进行替换,此处先进行删除
			this.configurationClasses.remove(configClass);
			this.knownSuperclasses.values().removeIf(configClass::equals);
		}
	}

	// 递归处理当前类及其父类
	SourceClass sourceClass = asSourceClass(configClass, filter);
	do {
		sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
	}
	while (sourceClass != null);

	this.configurationClasses.put(configClass, configClass);
}

真正处理时,先将其封装成一个 SourceClass 对象。下面来看下封装的过程。

private SourceClass asSourceClass(ConfigurationClass configurationClass, Predicate<String> filter) throws IOException {
	AnnotationMetadata metadata = configurationClass.getMetadata();
	if (metadata instanceof StandardAnnotationMetadata) {
		return asSourceClass(((StandardAnnotationMetadata) metadata).getIntrospectedClass(), filter);
	}
	return asSourceClass(metadata.getClassName(), filter);
}

SourceClass asSourceClass(@Nullable String className, Predicate<String> filter) throws IOException {
	if (className == null || filter.test(className)) {
		return this.objectSourceClass;
	}
	if (className.startsWith("java")) {
		// Never use ASM for core java types
		// java 包下的类,去加载,然后封装 SourceClass
		try {
			return new SourceClass(ClassUtils.forName(className, this.resourceLoader.getClassLoader()));
		}
		catch (ClassNotFoundException ex) {
			throw new org.springframework.core.NestedIOException("Failed to load class [" + className + "]", ex);
		}
	}
	return new SourceClass(this.metadataReaderFactory.getMetadataReader(className));
}

从前面的介绍可以知道,在创建 ConfigurationClassParser 时,将 ConfigurationClassPostProcessor 中的 metadataReaderFactory 传递给了 ConfigurationClassParser 构造方法,所以此时就是利用这个 metadataReaderFactory 来执行 getMetadataReader 方法获取 MetadataReader。此时的 metadataReaderFactory 为 CachingMetadataReaderFactory,传入 className,调入父类 SimpleMetadataReaderFactory。

@Override
public MetadataReader getMetadataReader(String className) throws IOException {
	try {
		String resourcePath = ResourceLoader.CLASSPATH_URL_PREFIX +
				ClassUtils.convertClassNameToResourcePath(className) + ClassUtils.CLASS_FILE_SUFFIX;
		// 处理完 resourcePath = classpath:com/icheetor/annotation/service/impl/UserServiceImpl.class
		Resource resource = this.resourceLoader.getResource(resourcePath);
		// 调用回子类方法 CachingMetadataReaderFactory#getMetadataReader 去执行
		return getMetadataReader(resource);
	}
	catch (FileNotFoundException ex) {
		// 可能是一个内部类,应用了 '.' 语法,此处应使用 '$' 语法
		int lastDotIndex = className.lastIndexOf('.');
		if (lastDotIndex != -1) {
			String innerClassName =
					className.substring(0, lastDotIndex) + '$' + className.substring(lastDotIndex + 1);
			String innerClassResourcePath = ResourceLoader.CLASSPATH_URL_PREFIX +
					ClassUtils.convertClassNameToResourcePath(innerClassName) + ClassUtils.CLASS_FILE_SUFFIX;
			Resource innerClassResource = this.resourceLoader.getResource(innerClassResourcePath);
			if (innerClassResource.exists()) {
				return getMetadataReader(innerClassResource);
			}
		}
		throw ex;
	}
}
// DefaultResourceLoader
@Override
public Resource getResource(String location) {
	Assert.notNull(location, "Location must not be null");

	for (ProtocolResolver protocolResolver : getProtocolResolvers()) {
		Resource resource = protocolResolver.resolve(location, this);
		if (resource != null) {
			return resource;
		}
	}

	if (location.startsWith("/")) {
		return getResourceByPath(location);
	}
	else if (location.startsWith(CLASSPATH_URL_PREFIX)) {
		// 创建一个 ClassPathResource
		return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
	}
	else {
		try {
			// Try to parse the location as a URL...
			URL url = new URL(location);
			return (ResourceUtils.isFileURL(url) ? new FileUrlResource(url) : new UrlResource(url));
		}
		catch (MalformedURLException ex) {
			// No URL -> resolve as resource path.
			return getResourceByPath(location);
		}
	}
}

先将 className 处理成资源 Resource。前面的介绍,CachingMetadataReaderFactory 中 resourceLoader 为 ApplicationContext,抽象实现 AbstractApplicationContext 继承 DefaultResourceLoader,所以调用 DefaultResourceLoader#getResource 创建一个 ClassPathResource 对象。接着再对这个资源对象,调用 CachingMetadataReaderFactory#getMetadataReader,缓存不存在,调用父类方法 SimpleMetadataReaderFactory#getMetadataReader。

@Override
public MetadataReader getMetadataReader(Resource resource) throws IOException {
	return new SimpleMetadataReader(resource, this.resourceLoader.getClassLoader());
}

接着会再次通过 ASM 中的 ClassReader 对字节码文件发起访问,最后返回封装了类相关信息的 SimpleMetadataReader 对象。此处可参考 spring 中的字节码文件访问 – classreading 包
访问注解时,由于之前包扫描时已经访问过一次,在 AnnotationTypeMappings 中存在 standardRepeatablesCache 缓存,所以直接从缓存中获取到了 AnnotationTypeMappings。只有注解访问结束,即 MergedAnnotationReadingVisitor#visitEnd,调用 MergedAnnotation#of 创建 TypeMappedAnnotation 对象,和整个字节码文件访问结束 SimpleAnnotationMetadataReadingVisitor#visitEnd,调用MergedAnnotations#of 创建 MergedAnnotationsCollection 对象,这两个对象为新建的,但这两个创建过程都不是耗时操作,只有针对某个 annotationType 创建 AnnotationTypeMappings 比较耗时,但 spring 已通过缓存进行了优化,具体可参靠 spring 中的注解操作 – annotation 包

public SourceClass(Object source) {
	this.source = source;
	if (source instanceof Class) {
		this.metadata = AnnotationMetadata.introspect((Class<?>) source);
	}
	else {
		this.metadata = ((MetadataReader) source).getAnnotationMetadata();
	}
}

获取到 SimpleMetadataReader 之后,调用 SourceClass 构造方法,为 metadata 赋值,即 SimpleAnnotationMetadata 对象。
接着执行真正的解析,ConfigurationClassParser#doProcessConfigurationClass。

配置类解析 doProcessConfigurationClass

@Nullable
protected final SourceClass doProcessConfigurationClass(
		ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
		throws IOException {
	
	// 持有 @Component
	if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
		// 递归处理其内部类,将每个内部类处理成 SourceClass,接着调用 processConfigurationClass
		processMemberClasses(configClass, sourceClass, filter);
	}

	// 处理 @PropertySource 注解
	for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
			sourceClass.getMetadata(), PropertySources.class,
			org.springframework.context.annotation.PropertySource.class)) {
		if (this.environment instanceof ConfigurableEnvironment) {
			processPropertySource(propertySource);
		}
		else {
			...
		}
	}

	// 处理 @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) {
			// 被 @ComponentScan 修饰的配置类,立即扫描
			Set<BeanDefinitionHolder> scannedBeanDefinitions =
					this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
			// 检查扫描到的 BeanDefinition,判断是否存在配置类,递归解析
			for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
				BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
				if (bdCand == null) {
					bdCand = holder.getBeanDefinition();
				}
				if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
					parse(bdCand.getBeanClassName(), holder.getBeanName());
				}
			}
		}
	}

	// 处理 @Import 注解
	processImports(configClass, sourceClass, getImports(sourceClass), filter, true);

	// 处理 @ImportResource 注解
	AnnotationAttributes importResource =
			AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
	if (importResource != null) {
		String[] resources = importResource.getStringArray("locations");
		Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
		for (String resource : resources) {
			String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
			configClass.addImportedResource(resolvedResource, readerClass);
		}
	}

	// 处理每一个 @Bean 方法
	// 遍历类访问时获取到的 SimpleAnnotationMetadata 中 annotatedMethods,判断注解类型是否是 @Bean,是,加入集合返回
	Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
	for (MethodMetadata methodMetadata : beanMethods) {
		configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
	}

	// 递归处理接口上的 @Bean 默认方法
	processInterfaces(configClass, sourceClass);

	// 处理父类
	if (sourceClass.getMetadata().hasSuperClass()) {
		String superclass = sourceClass.getMetadata().getSuperClassName();
		if (superclass != null && !superclass.startsWith("java") &&
				!this.knownSuperclasses.containsKey(superclass)) {
			this.knownSuperclasses.put(superclass, configClass);
			// Superclass found, return its annotation metadata and recurse
			// 找到父类,返回注解元数据,并递归
			return sourceClass.getSuperClass();
		}
	}

	// 无父类,处理完成
	return null;
}

在这里,spring-context 模块下 org.springframework.context.annotation 包中定义的配置类相关注解的解析都实现了。
处理完成之后,将 configClass 加入 configurationClasses。

配置类中 BeanDefinition 的注册 loadBeanDefinitions

对配置类解析完成后,创建一个 ConfigurationClassBeanDefinitionReader 对象,完成对配置类中 BeanDefinition 的加载。

public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
	TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
	for (ConfigurationClass configClass : configurationModel) {
		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;
	}

	// configClass 是 imported
	if (configClass.isImported()) {
		registerBeanDefinitionForImportedConfigurationClass(configClass);
	}
	// 处理 @Bean
	for (BeanMethod beanMethod : configClass.getBeanMethods()) {
		loadBeanDefinitionsForBeanMethod(beanMethod);
	}

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

下面主要看下 @Bean 定义的 BeanDefinition 的加载。

// 处理 @Bean
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
	// 定义 beanMethod 的配置类
	ConfigurationClass configClass = beanMethod.getConfigurationClass();
	// SimpleMethodMetadata
	MethodMetadata metadata = beanMethod.getMetadata();
	String methodName = metadata.getMethodName();

	// 判断是否需要跳过
	if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) {
		configClass.skippedBeanMethods.add(methodName);
		return;
	}
	if (configClass.skippedBeanMethods.contains(methodName)) {
		return;
	}

	// 获取 @Bean 上的属性
	AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
	Assert.state(bean != null, "No @Bean annotation attributes");

	// 定义 beanName,可以看到,当存在 name 属性时,取第一个,不存在,取方法名作为 beanName
	List<String> names = new ArrayList<>(Arrays.asList(bean.getStringArray("name")));
	String beanName = (!names.isEmpty() ? names.remove(0) : methodName);

	// 注册别名
	for (String alias : names) {
		this.registry.registerAlias(beanName, alias);
	}

	// 这个 beanName 是否之前已经存在,比如通过 xml 配置过
	if (isOverriddenByExistingDefinition(beanMethod, beanName)) {
		if (beanName.equals(beanMethod.getConfigurationClass().getBeanName())) {
			throw ...
		}
		return;
	}

	// 配置类中的 BeanDefinition 定义为 ConfigurationClassBeanDefinition
	ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata, beanName);
	beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));

	if (metadata.isStatic()) {
		// static @Bean method
		if (configClass.getMetadata() instanceof StandardAnnotationMetadata) {
			beanDef.setBeanClass(((StandardAnnotationMetadata) configClass.getMetadata()).getIntrospectedClass());
		}
		else {
			beanDef.setBeanClassName(configClass.getMetadata().getClassName());
		}
		beanDef.setUniqueFactoryMethodName(methodName);
	}
	else {
		// instance @Bean method
		// 将 configClass 的 beanName 作为 beanDef 的 factoryBeanName
		beanDef.setFactoryBeanName(configClass.getBeanName());
		// methodName 作为 factoryMethodName
		beanDef.setUniqueFactoryMethodName(methodName);
	}

	if (metadata instanceof StandardMethodMetadata) {
		beanDef.setResolvedFactoryMethod(((StandardMethodMetadata) metadata).getIntrospectedMethod());
	}

	// 设置注解属性
	beanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
	beanDef.setAttribute(org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor.
			SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);

	AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);

	Autowire autowire = bean.getEnum("autowire");
	if (autowire.isAutowire()) {
		beanDef.setAutowireMode(autowire.value());
	}

	boolean autowireCandidate = bean.getBoolean("autowireCandidate");
	if (!autowireCandidate) {
		beanDef.setAutowireCandidate(false);
	}

	String initMethodName = bean.getString("initMethod");
	if (StringUtils.hasText(initMethodName)) {
		beanDef.setInitMethodName(initMethodName);
	}

	String destroyMethodName = bean.getString("destroyMethod");
	beanDef.setDestroyMethodName(destroyMethodName);

	// @Scope,定义在 @Bean 方法上的 @Scope
	ScopedProxyMode proxyMode = ScopedProxyMode.NO;
	AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(metadata, Scope.class);
	if (attributes != null) {
		beanDef.setScope(attributes.getString("value"));
		proxyMode = attributes.getEnum("proxyMode");
		if (proxyMode == ScopedProxyMode.DEFAULT) {
			proxyMode = ScopedProxyMode.NO;
		}
	}

	// proxyMode 不为 ScopedProxyMode.NO,替换 beanDef
	BeanDefinition beanDefToRegister = beanDef;
	if (proxyMode != ScopedProxyMode.NO) {
		BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy(
				new BeanDefinitionHolder(beanDef, beanName), this.registry,
				proxyMode == ScopedProxyMode.TARGET_CLASS);
		beanDefToRegister = new ConfigurationClassBeanDefinition(
				(RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata, beanName);
	}

	// 注册 BeanDefinition
	this.registry.registerBeanDefinition(beanName, beanDefToRegister);
}

可以看到,将 @Bean 修饰的方法,最终封装成了一个 BeanDefinition,注册到 BeanFactory 中。
这样也完成了配置类中 BeanDefinition 的加载。
在 ConfigurationClassPostProcessor#processConfigBeanDefinitions 方法的最后,当完成了对所有配置类的所有操作之后,会对 ConfigurationClassPostProcessor 中的 metadataReaderFactory,即 CachingMetadataReaderFactory 进行缓存清除。

public void clearCache() {
	if (this.metadataReaderCache instanceof LocalResourceCache) {
		synchronized (this.metadataReaderCache) {
			this.metadataReaderCache.clear();
		}
	}
	else if (this.metadataReaderCache != null) {
		setCacheLimit(DEFAULT_CACHE_LIMIT);
	}
}
public void setCacheLimit(int cacheLimit) {
	if (cacheLimit <= 0) {
		this.metadataReaderCache = null;
	}
	else if (this.metadataReaderCache instanceof LocalResourceCache) {
		((LocalResourceCache) this.metadataReaderCache).setCacheLimit(cacheLimit);
	}
	else {
		this.metadataReaderCache = new LocalResourceCache(cacheLimit);
	}
}

通过对 metadataReaderCache 赋值为新建的 LocalResourceCache 对象,完成对缓存的清除。
前面介绍过,目前在 spring 中,BeanDefinitionRegistryPostProcessor 的实现类只有一个,就是 ConfigurationClassPostProcessor,也实现了 PriorityOrdered 接口,所以当创建完 ConfigurationClassPostProcessor 实例对象,调用 invokeBeanDefinitionRegistryPostProcessors 之后,就完成了这部分的处理。

为配置类创建代理 invokeBeanFactoryPostProcessors

接着,调用到目前为止处理过的所有 BeanFactoryPostProcessor 的 postProcessBeanFactory 回调。从前面的类结构可知,ConfigurationClassPostProcessor 也是 BeanFactoryPostProcessor 实现类。

private static void invokeBeanFactoryPostProcessors(
		Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

	for (BeanFactoryPostProcessor postProcessor : postProcessors) {
		StartupStep postProcessBeanFactory = beanFactory.getApplicationStartup().start("spring.context.bean-factory.post-process")
				.tag("postProcessor", postProcessor::toString);
		postProcessor.postProcessBeanFactory(beanFactory);
		postProcessBeanFactory.end();
	}
}
// ConfigurationClassPostProcessor
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	int factoryId = System.identityHashCode(beanFactory);
	if (this.factoriesPostProcessed.contains(factoryId)) {
		throw ...
	}
	this.factoriesPostProcessed.add(factoryId);
	if (!this.registriesPostProcessed.contains(factoryId)) {
		// beanFactory 没有处理过,先调用 processConfigBeanDefinitions
		processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
	}

	enhanceConfigurationClasses(beanFactory);
	// 添加 BeanPostProcessor,为增强配置类服务,增强类默认实现 EnhancedConfiguration 接口,是一个标记接口
	beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}

相对于 ConfigurationClassPostProcessor,核心代码就是 enhanceConfigurationClasses,从方法名猜测,这是对配置类的增强。

public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
	StartupStep enhanceConfigClasses = this.applicationStartup.start("spring.context.config-classes.enhance");
	Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
	// 遍历注册的 beanName
	for (String beanName : beanFactory.getBeanDefinitionNames()) {
		BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
		Object configClassAttr = beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE);
		AnnotationMetadata annotationMetadata = null;
		MethodMetadata methodMetadata = null;
		if (beanDef instanceof AnnotatedBeanDefinition) {
			AnnotatedBeanDefinition annotatedBeanDefinition = (AnnotatedBeanDefinition) beanDef;
			annotationMetadata = annotatedBeanDefinition.getMetadata();
			methodMetadata = annotatedBeanDefinition.getFactoryMethodMetadata();
		}
		if ((configClassAttr != null || methodMetadata != null) && beanDef instanceof AbstractBeanDefinition) {
			
			AbstractBeanDefinition abd = (AbstractBeanDefinition) beanDef;
			if (!abd.hasBeanClass()) {
				boolean liteConfigurationCandidateWithoutBeanMethods =
						(ConfigurationClassUtils.CONFIGURATION_CLASS_LITE.equals(configClassAttr) &&
							annotationMetadata != null && !ConfigurationClassUtils.hasBeanMethods(annotationMetadata));
				if (!liteConfigurationCandidateWithoutBeanMethods) {
					try {
						// 加载 beanClass
						abd.resolveBeanClass(this.beanClassLoader);
					}
					catch (Throwable ex) {
						throw ...
					}
				}
			}
		}
		// 只有 configClassAttr 为 "full",才会加入 configBeanDefs
		if (ConfigurationClassUtils.CONFIGURATION_CLASS_FULL.equals(configClassAttr)) {
			if (!(beanDef instanceof AbstractBeanDefinition)) {
				throw ...
			}
			else if (logger.isInfoEnabled() && beanFactory.containsSingleton(beanName)) {
				...
			}
			configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
		}
	}
	if (configBeanDefs.isEmpty() || NativeDetector.inNativeImage()) {
		// 不需要增强
		enhanceConfigClasses.end();
		return;
	}

	// 利用 cglib 动态生成子类 Class,完成增强
	ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
	for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
		AbstractBeanDefinition beanDef = entry.getValue();
		// If a @Configuration class gets proxied, always proxy the target class
		beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);

		Class<?> configClass = beanDef.getBeanClass();
		Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
		if (configClass != enhancedClass) {
			// 替换
			beanDef.setBeanClass(enhancedClass);
		}
	}
	enhanceConfigClasses.tag("classCount", () -> String.valueOf(configBeanDefs.keySet().size())).end();
}

在 ConfigurationClassPostProcessor#processConfigBeanDefinitions 时,会调用 ConfigurationClassUtils#checkConfigurationClassCandidate 获取 @Configuration 注解属性,根据配置的 proxyBeanMethods 来决定是否应该对 @Bean 方法进行拦截代理,默认 true。
所以当配置类上注解为 @Configuration 时,会通过 Cglib 为配置类生成一个代理类,即此处的 enhancedClass,作为配置类对应 BeanDefinition 的 beanClass。
这样,在创建配置类所对应的实例对象时,如果进行了增强,则默认实现 EnhancedConfiguration 接口,此时填充对象,会调用 ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#postProcessProperties。

@Override
public PropertyValues postProcessProperties(@Nullable PropertyValues pvs, Object bean, String beanName) {
	// Inject the BeanFactory before AutowiredAnnotationBeanPostProcessor's
	// postProcessProperties method attempts to autowire other configuration beans.
	if (bean instanceof EnhancedConfiguration) {
		((EnhancedConfiguration) bean).setBeanFactory(this.beanFactory);
	}
	return pvs;
}

此时会调用 setBeanFactory 方法,由于增强时设置了拦截器,会调用到 ConfigurationClassEnhancer$BeanFactoryAwareMethodInterceptor 中intercept 方法,其实就是给增强的代理 bean 对象设置 beanFactory 属性。
接着在初始化时,执行 AbstractAutowireCapableBeanFactory#invokeAwareMethods 时,由于 EnhancedConfiguration 继承 BeanFactoryAware 接口,所以又会调用 ConfigurationClassEnhancer.BeanFactoryAwareMethodInterceptor#intercept 方法。

@Bean 方法

@Bean 一般与 @Configuration 同时出现,封装 ConfigurationClassBeanDefinitionReader$ConfigurationClassBeanDefinition 时,配置类被看作工厂类,@Bean 方法被看作工厂方法,所以实例化时,会调用 AbstractAutowireCapableBeanFactory#instantiateUsingFactoryMethod

protected BeanWrapper instantiateUsingFactoryMethod(
		String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {

	return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}
// ConstructorResolver
public BeanWrapper instantiateUsingFactoryMethod(
		String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {

	BeanWrapperImpl bw = new BeanWrapperImpl();
	this.beanFactory.initBeanWrapper(bw);

	Object factoryBean;
	Class<?> factoryClass;
	boolean isStatic;

	// 获取工厂 beanName
	String factoryBeanName = mbd.getFactoryBeanName(); 
	if (factoryBeanName != null) {
		if (factoryBeanName.equals(beanName)) {
			throw ...
		}
		// 获取 factoryBean
		// 如果工厂 bean 未实例化,先对工厂 bean 进行实例化
		factoryBean = this.beanFactory.getBean(factoryBeanName);
		if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
			throw new ImplicitlyAppearedSingletonException();
		}
		this.beanFactory.registerDependentBean(factoryBeanName, beanName);
		factoryClass = factoryBean.getClass();
		isStatic = false;
	}
	else {
		// static 方法
		if (!mbd.hasBeanClass()) {
			throw ...
		}
		factoryBean = null;
		factoryClass = mbd.getBeanClass();
		isStatic = true;
	}

	Method factoryMethodToUse = null;
	ArgumentsHolder argsHolderToUse = null;
	Object[] argsToUse = null;

	if (explicitArgs != null) {
		argsToUse = explicitArgs;
	}
	else {
		Object[] argsToResolve = null;
		synchronized (mbd.constructorArgumentLock) {
			factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
			if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
				// Found a cached factory method...
				argsToUse = mbd.resolvedConstructorArguments;
				if (argsToUse == null) {
					argsToResolve = mbd.preparedConstructorArguments;
				}
			}
		}
		if (argsToResolve != null) {
			argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve);
		}
	}

	if (factoryMethodToUse == null || argsToUse == null) {
		// 针对 Cglib 代理类,获取的是其父类,即目标类
		// com.icheetor.annotation.service.impl.UserServiceImpl
		factoryClass = ClassUtils.getUserClass(factoryClass);  

		List<Method> candidates = null;
		if (mbd.isFactoryMethodUnique) {
			if (factoryMethodToUse == null) {
				// 获取工厂方法
				factoryMethodToUse = mbd.getResolvedFactoryMethod();
			}
			if (factoryMethodToUse != null) {
				candidates = Collections.singletonList(factoryMethodToUse);
			}
		}
		if (candidates == null) {
			candidates = new ArrayList<>();
			Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
			for (Method candidate : rawCandidates) {
				if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
					candidates.add(candidate);
				}
			}
		}

		if (candidates.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
			Method uniqueCandidate = candidates.get(0);
			// 无参情况,即不依赖其它 bean
			if (uniqueCandidate.getParameterCount() == 0) {
				mbd.factoryMethodToIntrospect = uniqueCandidate;
				synchronized (mbd.constructorArgumentLock) {
					mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
					mbd.constructorArgumentsResolved = true;
					mbd.resolvedConstructorArguments = EMPTY_ARGS;
				}
				// 实例化
				bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS));
				return bw;
			}
		}
		
		// 候选者多于一个,先排序,根据方法修饰符和参数个数排序
		if (candidates.size() > 1) {  
			candidates.sort(AutowireUtils.EXECUTABLE_COMPARATOR);
		}

		ConstructorArgumentValues resolvedValues = null;
		boolean autowiring = (mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
		int minTypeDiffWeight = Integer.MAX_VALUE;
		Set<Method> ambiguousFactoryMethods = null;

		int minNrOfArgs;
		if (explicitArgs != null) {
			minNrOfArgs = explicitArgs.length;
		}
		else {
			// constructor-arg
			// ConfigurationClassBeanDefinitionReader$ConfigurationClassBeanDefinition 类型的 BeanDefinition 实际上不存在
			if (mbd.hasConstructorArgumentValues()) {
				ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
				resolvedValues = new ConstructorArgumentValues();
				minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
			}
			else {
				minNrOfArgs = 0;
			}
		}

		Deque<UnsatisfiedDependencyException> causes = null;

		for (Method candidate : candidates) {
			int parameterCount = candidate.getParameterCount();

			if (parameterCount >= minNrOfArgs) {
				ArgumentsHolder argsHolder;

				// 获取参数类型
				Class<?>[] paramTypes = candidate.getParameterTypes();
				if (explicitArgs != null) {
					// 存在明确参数,给定参数长度必须和参数类型长度一致
					if (paramTypes.length != explicitArgs.length) {
						continue;
					}
					argsHolder = new ArgumentsHolder(explicitArgs);
				}
				else {
					// 解析构造参数
					try {
						// 解析参数名称
						String[] paramNames = null;
						// DefaultParameterNameDiscoverer
						ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
						if (pnd != null) {
							paramNames = pnd.getParameterNames(candidate);
						}
						// 解析依赖参数 bean
						argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw,
								paramTypes, paramNames, candidate, autowiring, candidates.size() == 1);
					}
					catch (UnsatisfiedDependencyException ex) {
						// 异常入列
						if (causes == null) {
							causes = new ArrayDeque<>(1);
						}
						causes.add(ex);
						continue;
					}
				}
				
				// 类型差异权重
				int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
						argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
				// 赋值
				if (typeDiffWeight < minTypeDiffWeight) {
					factoryMethodToUse = candidate;
					argsHolderToUse = argsHolder;
					argsToUse = argsHolder.arguments;
					minTypeDiffWeight = typeDiffWeight;
					ambiguousFactoryMethods = null;
				}
				// Find out about ambiguity: In case of the same type difference weight
				// for methods with the same number of parameters, collect such candidates
				// and eventually raise an ambiguity exception.
				// However, only perform that check in non-lenient constructor resolution mode,
				// and explicitly ignore overridden methods (with the same parameter signature).
				else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight &&
						!mbd.isLenientConstructorResolution() &&
						paramTypes.length == factoryMethodToUse.getParameterCount() &&
						!Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {
					if (ambiguousFactoryMethods == null) {
						ambiguousFactoryMethods = new LinkedHashSet<>();
						ambiguousFactoryMethods.add(factoryMethodToUse);
					}
					ambiguousFactoryMethods.add(candidate);
				}
			}
		}

		if (factoryMethodToUse == null || argsToUse == null) {
			if (causes != null) {
				UnsatisfiedDependencyException ex = causes.removeLast();
				for (Exception cause : causes) {
					this.beanFactory.onSuppressedException(cause);
				}
				throw ex;
			}
			List<String> argTypes = new ArrayList<>(minNrOfArgs);
			if (explicitArgs != null) {
				for (Object arg : explicitArgs) {
					argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null");
				}
			}
			else if (resolvedValues != null) {
				Set<ValueHolder> valueHolders = new LinkedHashSet<>(resolvedValues.getArgumentCount());
				valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());
				valueHolders.addAll(resolvedValues.getGenericArgumentValues());
				for (ValueHolder value : valueHolders) {
					String argType = (value.getType() != null ? ClassUtils.getShortName(value.getType()) :
							(value.getValue() != null ? value.getValue().getClass().getSimpleName() : "null"));
					argTypes.add(argType);
				}
			}
			String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes);
			// BeanCreationException
			throw ...
		}
		// 返回值类型不能为 void,@Bean 方法返回的是实例 bean
		else if (void.class == factoryMethodToUse.getReturnType()) {
			throw ...
		}
		// 模糊的工厂方法
		else if (ambiguousFactoryMethods != null) {
			throw ...
		}

		if (explicitArgs == null && argsHolderToUse != null) {
			mbd.factoryMethodToIntrospect = factoryMethodToUse;
			argsHolderToUse.storeCache(mbd, factoryMethodToUse);
		}
	}

	// instantiate 方法进行实例化
	bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));
	return bw;
}

代码比较长,核心逻辑如下:

  1. 确定工厂 bean,未实例化,先对工厂 bean 进行实例化
  2. 确定待使用的工厂方法,作为 candidates
  3. 如果 candidates 只有一个,并且工厂方法没有参数,即不依赖其它 bean,直接进行实例化,并将返回的半成品对象设置给 bw
  4. 当 candidates 有多个,或者只有一个,但工厂方法存在参数时,遍历 candidates,解析依赖的参数 bean,最终确定出要使用的工厂方法以及依赖的其它 bean 封装成的参数 argsToUse
  5. 实例化,并将返回的半成品对象设置给 bw

此处有一点需要注意,就是 @Bean 修饰的方法,方法参数表示对其它 bean 的依赖,相当于 xml 中定义的 ref=“someBean”,所以参数类型如果是基本类型会抛出异常。
下面来看下对依赖的参数 bean 的解析。

方法依赖参数解析 createArgumentArray

顾名思义,创建参数数组。

// ConstructorResolver
private ArgumentsHolder createArgumentArray(
		String beanName, RootBeanDefinition mbd, @Nullable ConstructorArgumentValues resolvedValues,
		BeanWrapper bw, Class<?>[] paramTypes, @Nullable String[] paramNames, Executable executable,
		boolean autowiring, boolean fallback) throws UnsatisfiedDependencyException {

	TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
	TypeConverter converter = (customConverter != null ? customConverter : bw);

	ArgumentsHolder args = new ArgumentsHolder(paramTypes.length);
	Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length);
	Set<String> autowiredBeanNames = new LinkedHashSet<>(4);

	for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
		Class<?> paramType = paramTypes[paramIndex];
		String paramName = (paramNames != null ? paramNames[paramIndex] : "");
		// Try to find matching constructor argument value, either indexed or generic.
		ConstructorArgumentValues.ValueHolder valueHolder = null;
		if (resolvedValues != null) {
			valueHolder = resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders);
			// If we couldn't find a direct match and are not supposed to autowire,
			// let's try the next generic, untyped argument value as fallback:
			// it could match after type conversion (for example, String -> int).
			if (valueHolder == null && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) {
				valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders);
			}
		}
		if (valueHolder != null) {
			// We found a potential match - let's give it a try.
			// Do not consider the same value definition multiple times!
			usedValueHolders.add(valueHolder);
			Object originalValue = valueHolder.getValue();
			Object convertedValue;
			if (valueHolder.isConverted()) {
				convertedValue = valueHolder.getConvertedValue();
				args.preparedArguments[paramIndex] = convertedValue;
			}
			else {
				MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
				try {
					convertedValue = converter.convertIfNecessary(originalValue, paramType, methodParam);
				}
				catch (TypeMismatchException ex) {
					throw new UnsatisfiedDependencyException...
				}
				Object sourceHolder = valueHolder.getSource();
				if (sourceHolder instanceof ConstructorArgumentValues.ValueHolder) {
					Object sourceValue = ((ConstructorArgumentValues.ValueHolder) sourceHolder).getValue();
					args.resolveNecessary = true;
					args.preparedArguments[paramIndex] = sourceValue;
				}
			}
			args.arguments[paramIndex] = convertedValue;
			args.rawArguments[paramIndex] = originalValue;
		}
		else {
			// 封装 MethodParameter
			MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
			// true
			if (!autowiring) {
				throw new UnsatisfiedDependencyException...
			}
			try {
				// 解决指定参数自动注入的模板方法
				// 解析完得到依赖的 bean 实例对象
				Object autowiredArgument = resolveAutowiredArgument(
						methodParam, beanName, autowiredBeanNames, converter, fallback);
				args.rawArguments[paramIndex] = autowiredArgument;
				args.arguments[paramIndex] = autowiredArgument;
				args.preparedArguments[paramIndex] = autowiredArgumentMarker;
				args.resolveNecessary = true;
			}
			catch (BeansException ex) {
				throw new UnsatisfiedDependencyException...
						
			}
		}
	}

	for (String autowiredBeanName : autowiredBeanNames) {
		this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
	}

	return args;
}

我们知道,@Bean 修饰的方法在配置类解析时都被处理成了 ConfigurationClassBeanDefinitionReader$ConfigurationClassBeanDefinition,而这个 BeanDefinition 是不存在 constructor-arg 的,所以方法中 resolvedValues 为 null,将 executable,此处即 Method,封装成 MethodParameter。接着调用 resolveAutowiredArgument。

@Nullable
protected Object resolveAutowiredArgument(MethodParameter param, String beanName,
		@Nullable Set<String> autowiredBeanNames, TypeConverter typeConverter, boolean fallback) {
	
	// 获取参数类型
	Class<?> paramType = param.getParameterType();
	if (InjectionPoint.class.isAssignableFrom(paramType)) {
		InjectionPoint injectionPoint = currentInjectionPoint.get();
		if (injectionPoint == null) {
			throw ...
		}
		return injectionPoint;
	}
	try {
		return this.beanFactory.resolveDependency(
				new DependencyDescriptor(param, true), beanName, autowiredBeanNames, typeConverter);
	}
	catch (NoUniqueBeanDefinitionException ex) {
		throw ex;
	}
	catch (NoSuchBeanDefinitionException ex) {
		// fallback 取决于 instantiateUsingFactoryMethod 中工厂方法 candidates 数量是否等于 1
		if (fallback) {
			if (paramType.isArray()) {
				return Array.newInstance(paramType.getComponentType(), 0);
			}
			else if (CollectionFactory.isApproximableCollectionType(paramType)) {
				return CollectionFactory.createCollection(paramType, 0);
			}
			else if (CollectionFactory.isApproximableMapType(paramType)) {
				return CollectionFactory.createMap(paramType, 0);
			}
		}
		throw ex;
	}
}

通过 beanFactory 完成对依赖的解析。具体可参考 spring 注解模式下对依赖的解析
得到 args 之后,通过 ConstructorResolver#instantiate 进行实例化。

// ConstructorResolver
private Object instantiate(String beanName, RootBeanDefinition mbd,
		@Nullable Object factoryBean, Method factoryMethod, Object[] args) {

	try {
		if (System.getSecurityManager() != null) {
			...
		}
		else {
			// 获取实例化策略,针对 beanName 进行实例化
			return this.beanFactory.getInstantiationStrategy().instantiate(
					mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args);
		}
	}
	catch (Throwable ex) {
		throw new BeanCreationException...
	}
}

获取 beanFactory 中配置的实例化策略,进行实例化,与 spring 中常规 bean 的实例化完成了统一。

// SimpleInstantiationStrategy
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
		@Nullable Object factoryBean, final Method factoryMethod, Object... args) {

	try {
		if (System.getSecurityManager() != null) {
			...
		}
		else {
			ReflectionUtils.makeAccessible(factoryMethod);
		}
		// ThreadLocal
		Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get();
		try {
			currentlyInvokedFactoryMethod.set(factoryMethod);
			// 工厂方法调用,如果 factoryBean 是 Cglib 增强过的,会调入对应 intercept 方法,例如 BeanMethodInterceptor
			Object result = factoryMethod.invoke(factoryBean, args);
			if (result == null) {
				result = new NullBean();
			}
			return result;
		}
		finally {
			if (priorInvokedFactoryMethod != null) {
				currentlyInvokedFactoryMethod.set(priorInvokedFactoryMethod);
			}
			else {
				currentlyInvokedFactoryMethod.remove();
			}
		}
	}
	catch (IllegalArgumentException ex) {
		throw ...
	}
	catch (IllegalAccessException ex) {
		throw ...
	}
	catch (InvocationTargetException ex) {
		throw ...
	}
}

通过工厂方法,反射完成对象的创建。此处有一点要注意,就是配置类如果是增强过的,即配置类是 Cglib 创建的代理对象,调用 invoke 方法时,会调入对应 intercept 方法,例如 BeanMethodInterceptor。

// org.springframework.context.annotation.ConfigurationClassEnhancer.BeanMethodInterceptor
@Override
@Nullable
public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,
			MethodProxy cglibMethodProxy) throws Throwable {
	
	// 获取 beanFactory
	ConfigurableBeanFactory beanFactory = getBeanFactory(enhancedConfigInstance);
	String beanName = BeanAnnotationHelper.determineBeanNameFor(beanMethod);

	// Determine whether this bean is a scoped-proxy
	if (BeanAnnotationHelper.isScopedProxy(beanMethod)) {
		String scopedBeanName = ScopedProxyCreator.getTargetBeanName(beanName);
		if (beanFactory.isCurrentlyInCreation(scopedBeanName)) {
			beanName = scopedBeanName;
		}
	}

	// To handle the case of an inter-bean method reference, we must explicitly check the
	// container for already cached instances.

	// First, check to see if the requested bean is a FactoryBean. If so, create a subclass
	// proxy that intercepts calls to getObject() and returns any cached bean instance.
	// This ensures that the semantics of calling a FactoryBean from within @Bean methods
	// is the same as that of referring to a FactoryBean within XML. See SPR-6602.
	if (factoryContainsBean(beanFactory, BeanFactory.FACTORY_BEAN_PREFIX + beanName) &&
			factoryContainsBean(beanFactory, beanName)) {
		Object factoryBean = beanFactory.getBean(BeanFactory.FACTORY_BEAN_PREFIX + beanName);
		if (factoryBean instanceof ScopedProxyFactoryBean) {
			// Scoped proxy factory beans are a special case and should not be further proxied
		}
		else {
			// It is a candidate FactoryBean - go ahead with enhancement
			return enhanceFactoryBean(factoryBean, beanMethod.getReturnType(), beanFactory, beanName);
		}
	}

	if (isCurrentlyInvokedFactoryMethod(beanMethod)) {
		if (logger.isInfoEnabled() &&
				BeanFactoryPostProcessor.class.isAssignableFrom(beanMethod.getReturnType())) {
			...
		}
		// MethodProxy 调用
		return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);
	}

	return resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
}

// MethodProxy
public Object invokeSuper(Object obj, Object[] args) throws Throwable {
	try {
		init();
		FastClassInfo fci = fastClassInfo;
		return fci.f2.invoke(fci.i2, obj, args);
	}
	catch (InvocationTargetException e) {
		throw e.getTargetException();
	}
}

通过 cglibMethodProxy 去执行,其实是进行了一个二次代理,这样完成之后,直接转化为对父类方法的调用,减少了反射调用的开销。
举个例子:

// 二次代理后生成
// var1  fci.i2  6
// var2  obj  一次代理后创建的对象 
public Object invoke(int var1, Object var2, Object[] var3) throws InvocationTargetException {
	3180d523 var10000 = (3180d523)var2;
	int var10001 = var1;

	try {
		switch(var10001) {
		case 0:
			...
		case 6:
			return var10000.CGLIB$initSchool$1();
		...
		}
	} catch (Throwable var4) {
		throw new InvocationTargetException(var4);
	}

	throw new IllegalArgumentException("Cannot find matching method/constructor");
}
// 配置类第一次被代理时生成这个方法
final School CGLIB$initSchool$1() {
	return super.initSchool();
}
 @Bean
public School initSchool() {
	return new School("清华大学");
}

从网上的相关介绍来看,这种方式虽然生成了二次代理,然后才完成了方法调用,但是性能上还是要优于直接的反射调用的。自 spring 5.2 之后,@Configuration 中新增了 proxyBeanMethods 属性,用来控制是否对配置类进行代理,也算是性能上的一种优化。
创建完成之后,将实例化对象填充进 bw,之后的处理就和 spring 中普通实例对象的处理一致了。

写在最后

顺便说下,注解模式本身是对 XML 模式的一种补充,采用注解模式,配置简单直观,但每次修改都需重新编译代码,而 XML 模式,修改 XML 后,无需重新编译代码,重新启动项目即可。并且,当注解和 XML 共同使用时,XML 的优先级是要高于注解的,这样如果需要修改,直接修改 XML 重启项目即可。

  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潭影空人心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值