文章目录
- Spring源码分析(@Configuration)
- 一、ConfigurationClassPostProcessor
- 1、主要作用和特点
- 2、执行的时机
- 3、BeanFactoryPostProcessor
- 4、BeanDefinitionRegistryPostProcessor
- 5、ConfigurationClassPostProcessor
- 1)postProcessBeanDefinitionRegistry
- 2)postProcessBeanFactory
- 二、processConfigBeanDefinitions
- 0、整体流程
- 1)源码分析
- 2)小结
- 1、获取配置类候选
- 1)源码分析
- 2)小结
- 2、解析 parse
- 1)源码分析
- 2)小结
- 2.1 processConfigurationClass
- 2.2 doProcessConfigurationClass(核心)
- 1)源码分析
- 2)@Component 的处理
- 3)@ComponentScan 的处理
- 4)@Import 的处理
- 5)小结
- 2.3 DeferredImportSelector 的处理
- 3、注册 loadBeanDefinitions
- 1)源码分析
- 2)小结
- 三、enhanceConfigurationClasses
- 1、增强逻辑
- 2、策略
- 3、三个拦截器
- 1)BeanFactoryAwareMethodInterceptor
- 2)BeanMethodInterceptor
- 4、小结
Spring源码分析(@Configuration)
一、ConfigurationClassPostProcessor
ConfigurationClassPostProcessor 是 Spring 框架中的一个后置处理器,主要用于处理带有 @Configuration
注解的配置类。它在 Spring 容器启动时会扫描并解析这些配置类,并进行相关的处理。
1、主要作用和特点
以下是 ConfigurationClassPostProcessor
的主要作用和特点:
-
处理配置类:
主要用于处理带有
@Configuration
注解的配置类。扫描并解析这些配置类,并将其中声明的 Bean 定义注册到容器中。 -
支持组件扫描:
在扫描配置类时,还会处理
@Component
、@ComponentScan
、@Import
、@ImportResource
等注解 -
处理@Bean注解:
对于配置类中使用
@Bean
注解声明的方法,会解析这些方法并将其返回的对象注册为 Spring Bean。 -
处理条件注解:
根据条件注解决定是否注册 Bean。如
@ConditionalOnBean
、@ConditionalOnMissingBean
等 -
处理代理模式:
在需要使用代理模式的情况下,会对配置类进行处理,确保代理模式的正确使用。
-
处理组件依赖:
会处理配置类之间的依赖关系,确保配置类之间的依赖关系正确解析并注册到容器中。
总的来说,ConfigurationClassPostProcessor
在 Spring 容器启动过程中起着至关重要的作用,它负责扫描、解析和注册带有 @Configuration
注解的配置类,是 Spring 容器实现组件自动装配和依赖注入的重要组成部分。
2、执行的时机
ConfigurationClassPostProcessor
是在 refresh
的 invokeBeanFactoryPostProcessors
方法中执行的
// org.springframework.context.support.AbstractApplicationContext
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 委托 PostProcessorRegistrationDelegate 循环执行每个 BeanFactoryPostProcessor
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// ...
}
PostProcessorRegistrationDelegate
的 invokeBeanFactoryPostProcessors
方法中,重点关注以下内容
// org.springframework.context.support.PostProcessorRegistrationDelegate
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// ...
// 循环调用 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry 方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 循环调用 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
// ...
}
可以看到 currentRegistryProcessors
和 registryProcessors
都包含 ConfigurationClassPostProcessor
3、BeanFactoryPostProcessor
@FunctionalInterface
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
- 作用:在容器已经加载了 BeanDefinition 并且实例化了部分 Bean 之后,对已经注册的 Bean 进行进一步的修改、添加或删除。
- 时机:在 Spring 容器加载了 Bean 定义并实例化了部分 Bean 之后,但在其余 Bean 实例化之前调用。
- 扩展:开发者可以实现
BeanFactoryPostProcessor
接口来自定义 BeanFactory 的后置处理行为。
4、BeanDefinitionRegistryPostProcessor
// 继承于 BeanFactoryPostProcessor
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
- 作用:在 BeanDefinition 被加载到容器之后、实例化之前,对 BeanDefinition 进行修改、添加或删除。
- 时机:在 Spring 容器加载 Bean 定义后,但在实例化 Bean 之前调用。
- 扩展:开发者可以实现
BeanDefinitionRegistryPostProcessor
接口来自定义 BeanDefinition 的注册行为。
5、ConfigurationClassPostProcessor
ConfigurationClassPostProcessor
实现了BeanDefinitionRegistryPostProcessor
接口BeanDefinitionRegistryPostProcessor
继承于BeanFactoryPostProcessor
接口
因此,ConfigurationClassPostProcessor
是这两个接口的子类,重写了这两个接口的两个方法
- 先执行
BeanDefinitionRegistryPostProcessor
的postProcessBeanDefinitionRegistry
- 再执行
BeanFactoryPostProcessor
的postProcessBeanFactory
1)postProcessBeanDefinitionRegistry
// org.springframework.context.annotation.ConfigurationClassPostProcessor
/**
* Derive further bean definitions from the configuration classes in the registry.
*/
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
// 生成一个registryId,防止重复执行
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);
}
// 保存已经执行的registryId,防止重复执行
this.registriesPostProcessed.add(registryId);
// 根据配置类,收集到所有的bd信息(也是@Import解析的入口时机,SpringBoot的启动类上也是一个@Configuration)
processConfigBeanDefinitions(registry);
}
2)postProcessBeanFactory
// org.springframework.context.annotation.ConfigurationClassPostProcessor
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 生成一个factoryId,防止重复执行
int factoryId = System.identityHashCode(beanFactory);
// 若重复就抛出异常
if (this.factoriesPostProcessed.contains(factoryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + beanFactory);
}
// 保存已经执行的factoryId,防止重复执行
this.factoriesPostProcessed.add(factoryId);
if (!this.registriesPostProcessed.contains(factoryId)) {
// BeanDefinitionRegistryPostProcessor hook apparently not supported...
// Simply call processConfigurationClasses lazily at this point then.
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
}
// 增强配置类(代理的逻辑)
enhanceConfigurationClasses(beanFactory);
// 添加后置处理器 ImportAwareBeanPostProcessor
// 主要用于处理实现了 ImportAware 接口的 Bean
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}
二、processConfigBeanDefinitions
0、整体流程
1)源码分析
我们先来看一下 processConfigBeanDefinitions
方法的大体实现
// org.springframework.context.annotation.ConfigurationClassPostProcessor
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
// 遍历容器中的BeanDefinition,获取 configCandidates
String[] candidateNames = registry.getBeanDefinitionNames();
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
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));
}
}
// 不存在 configCandidates,直接返回
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);
});
// 初始化 BeanName生成器
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {
// 获取 internalConfigurationBeanNameGenerator
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
// 初始化 environment
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
// 构建 ConfigurationClassParser,后面 @Configuration 配置类的解析 将委托给这个对象
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 while 循环解析 configCandidates
do {
// 解析 configCandidates
parser.parse(candidates);
// 校验 configurationClasses
parser.validate();
// 移除已解析的,剩下的就是本次解析的
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// 注册本次解析的 ConfigurationClass 的 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);
// 清空 configCandidates
candidates.clear();
// 检查是否有未解析的配置类,如果有,添加到 candidates 继续执行 do while 循环
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());
}
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 注册为bean 以支持 ImportAware @Configuration classes
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
// IMPORT_REGISTRY_BEAN_NAME = ConfigurationClassPostProcessor.class.getName() + ".importRegistry"
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
// 清理缓存
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
2)小结
- 遍历容器中的BeanDefinition,获取 configCandidates
- 如果使用了 @Order 注解,就排个序
- 初始化 BeanName生成器 和 environment
- 构建 ConfigurationClassParser,后面 @Configuration 配置类的解析 将委托给这个对象
- do while 循环解析 configCandidates
- 解析:
ConfigurationClassParser # parse
- 注册:
ConfigurationClassBeanDefinitionReader # loadBeanDefinitions
- 解析:
- 注册
ConfigurationClassPostProcessor.class.getName() + ".importRegistry"
- 清理缓存
1、获取配置类候选
1)源码分析
// org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions
// 获取并遍历当前容器中所有的BeanDefinitionNames
String[] candidateNames = registry.getBeanDefinitionNames();
for (String beanName : candidateNames) {
// 获取BeanDefinition
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
// 属性中存在 configurationClass -> 已被当作配置类处理过
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
// 没有被当作配置类处理过 && 是 Configuration 候选 -> 加入候选列表
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// org.springframework.context.annotation.ConfigurationClassUtils
public static boolean checkConfigurationClassCandidate(
BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
String className = beanDef.getBeanClassName();
if (className == null || beanDef.getFactoryMethodName() != null) {
return false;
}
AnnotationMetadata metadata;
// ...
// 获取 @Configuration 注解的属性
Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
// proxyBeanMethods = true -> configurationClass = full(代理对象)
if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
}
// proxyBeanMethods = false -> configurationClass = lite(普通对象)
else if (config != null || isConfigurationCandidate(metadata)) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
}
// 不是 configuration 候选
else {
return false;
}
// 走到这里说明是 configuration 候选
// 如果使用了 @Order 注解,填充 order 属性(后面要排序)
Integer order = getOrder(metadata);
if (order != null) {
beanDef.setAttribute(ORDER_ATTRIBUTE, order);
}
return true;
}
// org.springframework.context.annotation.ConfigurationClassUtils
private static final Set<String> candidateIndicators = new HashSet<>(8);
static {
candidateIndicators.add(Component.class.getName());
candidateIndicators.add(ComponentScan.class.getName());
candidateIndicators.add(Import.class.getName());
candidateIndicators.add(ImportResource.class.getName());
}
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 注解声明的方法
try {
return metadata.hasAnnotatedMethods(Bean.class.getName());
}
catch (Throwable ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to introspect @Bean methods on class [" + metadata.getClassName() + "]: " + ex);
}
return false;
}
}
2)小结
- 遍历容器中所有的 BeanDefinition,筛选出 configCandidates。
@Configuration(proxyBeanMethods = true)
—> configurationClass = full(代理对象)@Configuration(proxyBeanMethods = false)
并且满足下列条件 —> configurationClass = lite(普通对象)- 不考虑 接口 或 注解
- 存在
@Component
、@ComponentScan
、@Import
、@ImportResource
中任意注解 - 存在
@Bean
注解声明的方法
- 如果使用了
@Order
注解,填充order
属性(后面会进行排序)
2、解析 parse
1)源码分析
先来看一下 ConfigurationClassParser
的 parse
方法
// org.springframework.context.annotation.ConfigurationClassParser
public void parse(Set<BeanDefinitionHolder> configCandidates) {
// 遍历解析
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
// 根据不同的BeanDefinition类型,执行不同的 parse 方法
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 ...
}
// 处理 DeferredImportSelector(SpringBoot自动装配就在这里处理)
this.deferredImportSelectorHandler.process();
}
不同的 BeanDefinition类型 会执行 不同的 parse
方法,如下所示
// org.springframework.context.annotation.ConfigurationClassParser
protected final void parse(@Nullable String className, String beanName) throws IOException {
Assert.notNull(className, "No bean class name for configuration class bean definition");
MetadataReader reader = this.metadataReaderFactory.getMetadataReader(className);
processConfigurationClass(new ConfigurationClass(reader, beanName), DEFAULT_EXCLUSION_FILTER);
}
protected final void parse(Class<?> clazz, String beanName) throws IOException {
processConfigurationClass(new ConfigurationClass(clazz, beanName), DEFAULT_EXCLUSION_FILTER);
}
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
}
但是不同的 parse
方法最终都会执行 processConfigurationClass
方法。
2)小结
- 遍历解析
configCandidates
- 根据不同的
BeanDefinition
类型,执行不同的parse
方法(最终都会执行processConfigurationClass
方法) - 处理
DeferredImportSelector
- SpringBoot 自动装配通过
@Import
引入了AutoConfigurationImportSelector
- 而
AutoConfigurationImportSelector
就继承于DeferredImportSelector
- 因此 SpringBoot 自动装配 就是在这进行处理的
- SpringBoot 自动装配通过
2.1 processConfigurationClass
// org.springframework.context.annotation.ConfigurationClassParser
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) {
// @Import重复引入,merge并直接返回
if (configClass.isImported()) {
if (existingClass.isImported()) {
// 合并 ConfigurationClass 的 importedBy 属性(是一个Set集合)
existingClass.mergeImportedBy(configClass);
}
return;
}
// 如果不是@Import导入的,说明当前配置类是显式定义的(说明一个类被定义了两次),移除旧的重新解析
else {
this.configurationClasses.remove(configClass);
this.knownSuperclasses.values().removeIf(configClass::equals);
}
}
// 递归处理 configClass 及其父类
SourceClass sourceClass = asSourceClass(configClass, filter);
do {
// 具体的解析(返回当前类型的父类,存在父类,则会循环解析;不存在父类,则返回null退出循环)
sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
}
while (sourceClass != null);
// 添加到已解析列表
this.configurationClasses.put(configClass, configClass);
}
可以看到,具体的解析是由 doProcessConfigurationClass
方法完成的。
2.2 doProcessConfigurationClass(核心)
下面看一下 doProcessConfigurationClass
方法,这也是具体处理 Configuration
的核心方法
1)源码分析
// org.springframework.context.annotation.ConfigurationClassParser
@Nullable
protected final SourceClass doProcessConfigurationClass(
ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
throws IOException {
// 处理 @Component
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// 递归处理当前类的内部类
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) {
// 将指定的配置文件加载到当前Spring环境中。
processPropertySource(propertySource);
} else { logger.info(...) }
}
// 处理 @ComponentScan
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
// 判断 @Conditional 注解
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
// 根据 @ComponentScan 的参数进行解析,构建 ClassPathBeanDefinitionScanner 进行 doScan 处理
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// 检查 scannedBeanDefinitions 以查找任何进一步的配置类,并在需要时递归地进行解析
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
// 如果扫描到的BeanDefinition是配置类候选,调用 processConfigurationClass 解析
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);
// 保存import的资源,后面 loadBeanDefinitions 统一处理
configClass.addImportedResource(resolvedResource, readerClass);
}
}
// 处理 @Bean 方法
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
// 保存添加了@Bean注解的方法,后面 loadBeanDefinitions 统一处理
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// 递归解析接口中的@Bean方法(A default method or other concrete method on a Java 8+ interface)
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();
}
}
// 如果没有父类,则返回null,结束外层的do while解析
return null;
}
2)@Component 的处理
// org.springframework.context.annotation.ConfigurationClassParser#doProcessConfigurationClass
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// 递归处理当前类的内部类
processMemberClasses(configClass, sourceClass, filter);
}
// org.springframework.context.annotation.ConfigurationClassParser
private void processMemberClasses(ConfigurationClass configClass, SourceClass sourceClass,
Predicate<String> filter) throws IOException {
// 获取 memberClasses
Collection<SourceClass> memberClasses = sourceClass.getMemberClasses();
if (!memberClasses.isEmpty()) {
List<SourceClass> candidates = new ArrayList<>(memberClasses.size());
// 遍历 memberClasses,添加 configCandidates
for (SourceClass memberClass : memberClasses) {
if (ConfigurationClassUtils.isConfigurationCandidate(memberClass.getMetadata()) &&
!memberClass.getMetadata().getClassName().equals(configClass.getMetadata().getClassName())) {
candidates.add(memberClass);
}
}
// 排序
OrderComparator.sort(candidates);
// 遍历 configCandidates
for (SourceClass candidate : candidates) {
if (this.importStack.contains(configClass)) {
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {
this.importStack.push(configClass);
try {
// configClass 作为 candidate 的 importedBy
processConfigurationClass(candidate.asConfigClass(configClass), filter);
}
finally {
this.importStack.pop();
}
}
}
}
}
3)@ComponentScan 的处理
// org.springframework.context.annotation.ConfigurationClassParser#doProcessConfigurationClass
// 解析 @ComponentScan 注解的属性
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
// 判断 @Conditional 注解
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
// 遍历 @ComponentScan 注解的属性
for (AnnotationAttributes componentScan : componentScans) {
// 根据 @ComponentScan 的属性进行解析,构建 ClassPathBeanDefinitionScanner 进行 doScan 处理
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();
}
// 判断 BeanDefinition 是否是 配置类候选
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
// 内部会调用 processConfigurationClass 解析
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
4)@Import 的处理
先通过getImports
方法解析@Import
导入的sourceClass
,再调用processImports
方法进行处理。
// org.springframework.context.annotation.ConfigurationClassParser#doProcessConfigurationClass
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
我们先看一下 @Import
注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
/**
* {@link Configuration @Configuration}, {@link ImportSelector},
* {@link ImportBeanDefinitionRegistrar}, or regular component classes to import.
*/
Class<?>[] value();
}
可以看到该注解可以导入:Configuration、ImportSelector、ImportBeanDefinitionRegistrar、常规的组件类
下面看一下 processImports
方法的处理
// org.springframework.context.annotation.ConfigurationClassParser
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter,
boolean checkForCircularImports) {
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) {
// 1. 导入的是 ImportSelector 类型
if (candidate.isAssignable(ImportSelector.class)) {
Class<?> candidateClass = candidate.loadClass();
ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class, this.environment, this.resourceLoader, this.registry);
Predicate<String> selectorFilter = selector.getExclusionFilter();
if (selectorFilter != null) {
exclusionFilter = exclusionFilter.or(selectorFilter);
}
// DeferredImportSelector 类型 --> 放入deferredImportSelectors中,后面统一处理
if (selector instanceof DeferredImportSelector) {
this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
}
// 非 DeferredImportSelector 类型 --> 直接调用 selector 的 selectImports 进行处理
else {
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
}
}
// 2. 导入的是 ImportBeanDefinitionRegistrar 类型
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
Class<?> candidateClass = candidate.loadClass();
// 构建 ImportBeanDefinitionRegistrar 实例
// 如果是 Aware,还会根据 Aware类型 填充相关属性
ImportBeanDefinitionRegistrar registrar =
ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class, this.environment, this.resourceLoader, this.registry);
// 保存 ImportBeanDefinitionRegistrar 实例,后面 loadBeanDefinitions 统一处理
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
// 3. 既不是 ImportSelector 也不是 ImportBeanDefinitionRegistrar
else {
// 按 @Configuration 类处理
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
// configClass 作为 candidate 的 importedBy
processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
}
}
}
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();
}
}
}
5)小结
-
处理
@Component
:- 递归处理当前类的内部类
- 如果内部类是配置类候选,调用
processConfigurationClass
解析
-
处理
@PropertySource
:- 将指定的配置文件加载到当前Spring环境中。
-
处理
@ComponentScan
:- 根据
@ComponentScan
的属性 构建ClassPathBeanDefinitionScanner
进行doScan
处理- 关于 doScan 的逻辑,可以参考 Spring源码分析(BeanDefinition),这里不再赘述。
- 如果扫描注册的
BeanDefinition
是配置类候选,调用processConfigurationClass
解析
- 根据
-
处理
@Import
:获取@Import
引入的资源,分为以下三类进行处理-
ImportSelector
类型:- DeferredImportSelector 类型 --> 放入deferredImportSelectors中,后面统一处理
- 非 DeferredImportSelector 类型 --> 直接调用 selector 的 selectImports 进行处理
-
ImportBeanDefinitionRegistrar
类型:-
构建 ImportBeanDefinitionRegistrar 实例(如果是 Aware,还会根据 Aware类型 填充相关属性)
-
将 构建的实例 暂存到
ConfigurationClass
的importBeanDefinitionRegistrars
属性在
loadBeanDefinitions
中统一处理。
-
-
其他类型:作为 @Configuration 类 处理,调用
processConfigurationClass
解析
-
-
处理
@ImportResource
:-
将 引入的资源 暂存到
ConfigurationClass
的importedResources
属性在
loadBeanDefinitions
中统一处理。
-
-
处理
@Bean
:-
将 标记的方法 暂存到
ConfigurationClass
的beanMethods
属性在
loadBeanDefinitions
中统一处理。
-
-
最后 会返回父类(没有父类返回null),用于决定外层 do while 是否需要继续循环处理。
2.3 DeferredImportSelector 的处理
在 parse
方法的最后,会对 DeferredImportSelector
进行统一的处理
// org.springframework.context.annotation.ConfigurationClassParser
public void parse(Set<BeanDefinitionHolder> configCandidates) {
// 遍历解析...
// 处理 DeferredImportSelector
this.deferredImportSelectorHandler.process();
}
SpringBoot 的自动装配就是在这里进行处理的。具体细节可以参考 SpringBoot源码分析(自动装配),这里不再赘述。
3、注册 loadBeanDefinitions
接着看一下 ConfigurationClassBeanDefinitionReader
的 loadBeanDefinitions
方法。
其实根据上面的阅读可以发现,前面解析时已经加载了很多BeanDefinition
了,但是对于有些情况只做了暂存,没有真正进行加载,而这些后续处理,正是在 ConfigurationClassBeanDefinitionReader # loadBeanDefinitions
完成的。
1)源码分析
// org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
// 遍历加载 parser 解析的 ConfigurationClass
for (ConfigurationClass configClass : configurationModel) {
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
}
}
private void loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
// 判断 @Conditional
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;
}
// ConfigurationClass 的 importedBy 属性不为空(@Import引入 / @Component的内部类)
if (configClass.isImported()) {
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
// 遍历 ConfigurationClass 的 beanMethods 属性
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
// `@Bean`注解标记的方法返回的bean,注册其 `BeanDefinition`
loadBeanDefinitionsForBeanMethod(beanMethod);
}
// 加载 @ImportResource 注解对应的资源
// 添加的时机:doProcessConfigurationClass -> @ImportResource 的处理
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
// 加载 @Import 引入的 ImportBeanDefinitionRegistrar 类型
// 添加的时机:doProcessConfigurationClass -> @Import 的处理(ImportBeanDefinitionRegistrar 类型)
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
2)小结
遍历加载 parser
解析的 ConfigurationClass
- 判断
@Conditional
- 注册
@Import
引入的配置类(parse 时填充,这里统一处理) - 加载
@Bean
注解标记的方法返回的bean(parse 时填充,这里统一处理) - 加载
@ImportResource
注解引入的资源(parse 时填充,这里统一处理) - 加载
@Import
注解引入的ImportBeanDefinitionRegistrar
(parse 时填充,这里统一处理)
关于 BeanDefinition
的注册,可以参考 Spring源码分析(BeanDefinition),这里不再赘述。
三、enhanceConfigurationClasses
// org.springframework.context.annotation.ConfigurationClassPostProcessor
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
// 获取所有的 BeanDefinitionName 并遍历(已完成 processConfigBeanDefinitions)
for (String beanName : beanFactory.getBeanDefinitionNames()) {
BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
// 获取 configurationClass 属性值
Object configClassAttr = beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE);
// ...
// 如果 configurationClass = full(需要代理)
if (ConfigurationClassUtils.CONFIGURATION_CLASS_FULL.equals(configClassAttr)) {
// ...
// 添加到 configBeanDefs
configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
}
}
if (configBeanDefs.isEmpty()) {
// nothing to enhance -> return immediately
return;
}
// 对配置类进行代理的核心类
ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
// 需要增强的 BeanDefinition
AbstractBeanDefinition beanDef = entry.getValue();
// 设置 preserveTargetClass = true,表示使用cglib动态代理
beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
// 要代理的类
Class<?> configClass = beanDef.getBeanClass();
// 对 full configClass 进行增强
Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
if (configClass != enhancedClass) {
// logger...
// 将 BeanDefinition 中的 beanClass 替换为 代理后的class
beanDef.setBeanClass(enhancedClass);
}
}
}
1、增强逻辑
下面看一下 ConfigurationClassEnhancer
中的 enhance
增强方法
// org.springframework.context.annotation.ConfigurationClassEnhancer
// 三个拦截器
private static final Callback[] CALLBACKS = new Callback[] {
new BeanMethodInterceptor(),
new BeanFactoryAwareMethodInterceptor(),
// 代表什么都没做
NoOp.INSTANCE
};
private static final ConditionalCallbackFilter CALLBACK_FILTER = new ConditionalCallbackFilter(CALLBACKS);
public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader) {
// 如果已经实现了EnhancedConfiguration接口,说明被代理过了,直接返回
if (EnhancedConfiguration.class.isAssignableFrom(configClass)) {
// logger...
return configClass;
}
// 先 newEnhancer 创建一个增强器,然后使用这个增强器生成代理类的Class对象
Class<?> enhancedClass = createClass(newEnhancer(configClass, classLoader));
// logger...
return enhancedClass;
}
private Enhancer newEnhancer(Class<?> configSuperClass, @Nullable ClassLoader classLoader) {
// org.springframework.cglib.proxy.Enhancer
// 这样可避免在应用程序级别或第三方库和框架上与CGLIB的依赖性发生任何潜在冲突
Enhancer enhancer = new Enhancer();
// 被代理的类
enhancer.setSuperclass(configSuperClass);
// 代理类实现了 EnhancedConfiguration 接口,EnhancedConfiguration 继承于 BeanFactoryAware 接口
// 1. 标记作用。如果实现了EnhancedConfiguration,代表已经被代理过了
// 2. 代理类需要访问BeanFactory,所有实现了BeanFactoryAware接口
enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});
// 代理类不实现 org.springframework.cglib.proxy.Factory 接口
enhancer.setUseFactory(false);
// 使用 SpringNamingPolicy 替代 默认的DefaultNamingPolicy
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
// 设置策略 BeanFactoryAwareGeneratorStrategy
enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));
// 设置过滤器,CALLBACK_FILTER包含三个拦截器
enhancer.setCallbackFilter(CALLBACK_FILTER);
enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
return enhancer;
}
// 使用增强器生成代理类的字节码对象
private Class<?> createClass(Enhancer enhancer) {
Class<?> subclass = enhancer.createClass();
Enhancer.registerStaticCallbacks(subclass, CALLBACKS);
return subclass;
}
2、策略
// org.springframework.context.annotation.ConfigurationClassEnhancer
private static class BeanFactoryAwareGeneratorStrategy extends ClassLoaderAwareGeneratorStrategy {
public BeanFactoryAwareGeneratorStrategy(@Nullable ClassLoader classLoader) {
super(classLoader);
}
@Override
protected ClassGenerator transform(ClassGenerator cg) throws Exception {
ClassEmitterTransformer transformer = new ClassEmitterTransformer() {
@Override
public void end_class() {
// 这个策略会在代理类中添加一个字段,BEAN_FACTORY_FIELD = "$$beanFactory"
declare_field(Constants.ACC_PUBLIC, BEAN_FACTORY_FIELD, Type.getType(BeanFactory.class), null);
super.end_class();
}
};
return new TransformingClassGenerator(cg, transformer);
}
}
3、三个拦截器
// org.springframework.context.annotation.ConfigurationClassEnhancer
private static final Callback[] CALLBACKS = new Callback[] {
new BeanMethodInterceptor(),
new BeanFactoryAwareMethodInterceptor(),
NoOp.INSTANCE
};
NoOp.INSTANCE
代表什么都没做,我们重点关注前面两个。
1)BeanFactoryAwareMethodInterceptor
BeanFactoryAwareMethodInterceptor
主要拦截 BeanFactoryAware
接口的 setBeanFactory
方法
// org.springframework.context.annotation.ConfigurationClassEnhancer
private static class BeanFactoryAwareMethodInterceptor implements MethodInterceptor, ConditionalCallback {
@Override
public boolean isMatch(Method candidateMethod) {
// 拦截的是setBeanFactory方法
return isSetBeanFactory(candidateMethod);
}
/**
* 从前文我们知道,代理类间接实现了 BeanFactoryAware 接口,
* 因此在创建配置类时,setBeanFactory方法就会被调用,之后就会进入拦截器的intercept方法
*/
public static boolean isSetBeanFactory(Method candidateMethod) {
return (candidateMethod.getName().equals("setBeanFactory") &&
candidateMethod.getParameterCount() == 1 &&
BeanFactory.class == candidateMethod.getParameterTypes()[0] &&
BeanFactoryAware.class.isAssignableFrom(candidateMethod.getDeclaringClass()));
}
@Override
@Nullable
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
// 在生成代理类的字节码时,使用了BeanFactoryAwareGeneratorStrategy策略
// 这个策略会在代理类中添加一个字段,BEAN_FACTORY_FIELD = "$$beanFactory"
// 获取字段 BEAN_FACTORY_FIELD = "$$beanFactory"
Field field = ReflectionUtils.findField(obj.getClass(), BEAN_FACTORY_FIELD);
Assert.state(field != null, "Unable to find generated BeanFactory field");
// 通过反射将 beanFactory 赋值给 BEAN_FACTORY_FIELD
field.set(obj, args[0]);
// 如果目标配置类实现了 BeanFactoryAware 接口,则直接调用目标配置类的 setBeanFactory 方法
if (BeanFactoryAware.class.isAssignableFrom(ClassUtils.getUserClass(obj.getClass().getSuperclass()))) {
return proxy.invokeSuper(obj, args);
}
// 如果目标配置类没有实现 BeanFactoryAware 接口,则直接退出
return null;
}
}
2)BeanMethodInterceptor
BeanMethodInterceptor
主要拦截 @Bean
标注的方法。
// org.springframework.context.annotation.ConfigurationClassEnhancer
private static class BeanMethodInterceptor implements MethodInterceptor, ConditionalCallback {
@Override
public boolean isMatch(Method candidateMethod) {
return (
// 第一个条件,不能是Object,这个必定是满足的
candidateMethod.getDeclaringClass() != Object.class &&
// 第二个条件,不能是setBeanFactory方法(要拦截的方法实际只应该是添加了@Bean注解的方法)
!BeanFactoryAwareMethodInterceptor.isSetBeanFactory(candidateMethod) &&
// 第三个条件,添加了@Bean注解
BeanAnnotationHelper.isBeanAnnotated(candidateMethod));
}
}
下面来看一下 intercept
的逻辑
// org.springframework.context.annotation.ConfigurationClassEnhancer
private static class BeanMethodInterceptor implements MethodInterceptor, ConditionalCallback {
@Override
@Nullable
public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,
MethodProxy cglibMethodProxy) throws Throwable {
// 获取 beanFactory(之前不是给BEAN_FACTORY_FIELD赋值了吗,这里就是反射获取之前赋的值)
ConfigurableBeanFactory beanFactory = getBeanFactory(enhancedConfigInstance);
// 确定 beanName
String beanName = BeanAnnotationHelper.determineBeanNameFor(beanMethod);
// 判断这个Bean是否是一个域代理的类(存在@Scope注解,并且 proxyMode != NO)
if (BeanAnnotationHelper.isScopedProxy(beanMethod)) {
String scopedBeanName = ScopedProxyCreator.getTargetBeanName(beanName);
if (beanFactory.isCurrentlyInCreation(scopedBeanName)) {
beanName = scopedBeanName;
}
}
// 当前Bean 是 FactoryBean
if (factoryContainsBean(beanFactory, BeanFactory.FACTORY_BEAN_PREFIX + beanName) &&
factoryContainsBean(beanFactory, beanName)) {
Object factoryBean = beanFactory.getBean(BeanFactory.FACTORY_BEAN_PREFIX + beanName);
// ScopedProxyFactoryBean
if (factoryBean instanceof ScopedProxyFactoryBean) {
// 不需要进一步代理
}
// 普通的FactoryBean
else {
// 需要代理其getObject方法,确保通过 beanFactory.getBean(beanName) 创建bean
return enhanceFactoryBean(factoryBean, beanMethod.getReturnType(), beanFactory, beanName);
}
}
// 走到这,说明 当前Bean 不是 FactoryBean
// 举个例子,假设我们被@Bean标注的是A方法,当前创建的BeanName也是a,这样就符合了这个条件
// 但是如果是 a(){b()},a方法中使用b方法创建的b对象,那么此时调用b方法创建b对象时,正在执行的是a方法
// 此时就不满足这个条件,会调用resolveBeanReference方法来处理
if (isCurrentlyInvokedFactoryMethod(beanMethod)) {
// logger...
// 如果 当前执行的方法 就是 拦截的@Bean方法
return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);
}
// 如果 当前执行的方法 不是 拦截的@Bean方法。例如a(){b()},拦截的是a(),当前执行的是b()
return resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
}
}
接着看一下 resolveBeanReference
方法
// org.springframework.context.annotation.ConfigurationClassEnhancer
private Object resolveBeanReference(Method beanMethod, Object[] beanMethodArgs,
ConfigurableBeanFactory beanFactory, String beanName) {
// 判断bean是否正在创建中(在创建Bean之前,会先将Bean标记为正在创建)
boolean alreadyInCreation = beanFactory.isCurrentlyInCreation(beanName);
try {
// 如果是正在创建的Bean,先将正在创建标记置为false,避免后续调用getBean时报错
if (alreadyInCreation) {
beanFactory.setCurrentlyInCreation(beanName, false);
}
// @Bean注解标注的方法是否使用参数
boolean useArgs = !ObjectUtils.isEmpty(beanMethodArgs);
if (useArgs && beanFactory.isSingleton(beanName)) {
for (Object arg : beanMethodArgs) {
// 只要有一个参数为null,useArgs = false
if (arg == null) {
useArgs = false;
break;
}
}
}
// 通过 beanFactory.getBean 获取bean
// 1. 没有参数 或 存在参数为null -> 调用 getBean(beanName)
// 2. 存在参数 且 没有参数为null -> 调用 getBean(beanName, beanMethodArgs)
Object beanInstance = (useArgs ? beanFactory.getBean(beanName, beanMethodArgs) :
beanFactory.getBean(beanName));
// getBean返回的类型不是方法返回的类型
if (!ClassUtils.isAssignableValue(beanMethod.getReturnType(), beanInstance)) {
if (beanInstance.equals(null)) {
// logger...
beanInstance = null;
} else {
// logger...
throw new IllegalStateException(msg);
}
}
// currentlyInvoked 就是a(),beanName就是b,outerBeanName就是a
// currentlyInvoked != null 说明 currentlyInvoked创建的bean 依赖了 beanName代表的Bean
Method currentlyInvoked = SimpleInstantiationStrategy.getCurrentlyInvokedFactoryMethod();
if (currentlyInvoked != null) {
String outerBeanName = BeanAnnotationHelper.determineBeanNameFor(currentlyInvoked);
// 注册的就是a跟b的依赖关系,注册到容器中的dependentBeanMap中
// key为依赖,value为依赖所在的bean
beanFactory.registerDependentBean(beanName, outerBeanName);
}
return beanInstance;
}
finally {
if (alreadyInCreation) {
// 改回创建中,要走完整个生命周期流程
beanFactory.setCurrentlyInCreation(beanName, true);
}
}
}
4、小结
在 processConfigBeanDefinitions 之后,会执行 enhanceConfigurationClasses
- 筛选所有需要代理的配置类
- 存在 configurationClass 属性(即 @Configuration 修饰)
- 属性 configurationClass = full(即 @Configuration 的 proxyBeanMethods 属性值为 true,默认即为 true)
- 使用 cglib动态代理 进行增强
- 拦截
BeanFactoryAware
接口的setBeanFactory
方法,添加属性"$$beanFactory"
并赋值 - 拦截
@Bean
标注的方法- 处理 FactoryBean 的 getObject 方法,代理为 getBean(ScopedProxyFactoryBean不作处理)
- 处理
@Bean
标注的方法返回的bean之间的依赖关系
- 拦截