Spring容器
2021-04-13 21:39:36 0 举报
AI智能生成
Spring容器初始化的源码分析
作者其他创作
大纲/内容
AbstractApplicationContext是Spring容器的模板抽象类,ApplicationContext实现都继承了它。
实现接口
ConfigurableApplicationContext
ApplicationContext
ListableBeanFactory
支持根据条件查找一批bean而非一个bean
支持根据条件查找一批bean而非一个bean
BeanFactory
提供了一个基本的bean容器视图
提供了一个基本的bean容器视图
HierarchicalBeanFactory
提供容器层级支持,在本容器的操作也将检查父容器
支持重写父容器的bean
提供容器层级支持,在本容器的操作也将检查父容器
支持重写父容器的bean
BeanFactory
提供了一个基本的bean容器视图
提供了一个基本的bean容器视图
EnvironmentCapable
获取环境配置,ConfigurableApplicationContext收窄了返回类型ConfigurableEnvironment
获取环境配置,ConfigurableApplicationContext收窄了返回类型ConfigurableEnvironment
MessageSource
消息处理,提供消息的参数化和国际化处理
消息处理,提供消息的参数化和国际化处理
ApplicationEventPublisher
提供事件发布的支持,驱动事件监听
提供事件发布的支持,驱动事件监听
ResourcePatternResolver
使用表示资源路径的字符串来加载多个资源
提供classpath*前缀支持,支持通配符
使用表示资源路径的字符串来加载多个资源
提供classpath*前缀支持,支持通配符
ResourceLoader
使用标识资源路径的字符串来加载单个资源
提供classpath前缀支持
AAC继承了这个接口的实现类DefaultResourceLoader
使用标识资源路径的字符串来加载单个资源
提供classpath前缀支持
AAC继承了这个接口的实现类DefaultResourceLoader
Lifecycle
定义启停生命周期控制,典型用于控制异步处理
它只作用于顶级的单例bean
SmartLifecycle提供更复杂的功能支持
定义启停生命周期控制,典型用于控制异步处理
它只作用于顶级的单例bean
SmartLifecycle提供更复杂的功能支持
Closeable
JDK提供的接口,用于关闭时释放资源等处理
Spring容器中持有的bean可能包含资源的释放,
都会在该接口实现中统一调用
JDK提供的接口,用于关闭时释放资源等处理
Spring容器中持有的bean可能包含资源的释放,
都会在该接口实现中统一调用
AutoCloseable
支持try-resource语法
支持try-resource语法
简介
AC的抽象实现。不关注配置的存储类型;简单地实现了通用的容器功能。使用了模板方法设计模式,需要实体子类实现抽象方法。
和普通的BF相比,AC需要探测定义在内部BF中的一些特殊bean。该类自动注册了定义在容器中的BeanFactoryPostProcessor,BeanPostProcessor,ApplicationListener
可以配置bean名称为"messageSource"的MessageSource来处理消息;否则,消息的解析将委托给父容器。
可以配置bean名称为"applicationEventMulticaster"的ApplicationEventMulticaster来分发应用事件;否则,默认配置SimpleApplicationEventMulticaster
可以配置bean名称为"applicationEventMulticaster"的ApplicationEventMulticaster来分发应用事件;否则,默认配置SimpleApplicationEventMulticaster
继承了DefaultResourceLoader来实现资源的加载。
核心方法
refresh
prepareRefresh();
刷新上下文前准备
刷新上下文前准备
this.closed.set(false);
this.active.set(true);
设置AC状态
this.active.set(true);
设置AC状态
initPropertySources();
钩子方法:在上下文环境中指定初始化占位符属性源
钩子方法:在上下文环境中指定初始化占位符属性源
getEnvironment().validateRequiredProperties();
验证所有标记为必须的属性都可以解析。
ConfigurablePropertyResolver#setRequiredProperties
验证所有标记为必须的属性都可以解析。
ConfigurablePropertyResolver#setRequiredProperties
earlyApplicationListeners如果不为null,那么里面存的就是在pre-refresh之前注册到AC的监听器,只要调用过refresh方法就不会为null。
earlyApplicationEvents如果不为null,说明监听器还没有注册到applicationEventMulticaster,里面暂存的事件会等到监听器注册完毕后进行处理,处理完成后会置为null
earlyApplicationEvents如果不为null,说明监听器还没有注册到applicationEventMulticaster,里面暂存的事件会等到监听器注册完毕后进行处理,处理完成后会置为null
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
告诉子类刷新内部的BF,并返回刷新后的BF。内部调用两个方法都是抽象方法,待子类实现。
告诉子类刷新内部的BF,并返回刷新后的BF。内部调用两个方法都是抽象方法,待子类实现。
refreshBeanFactory();
return getBeanFactory();
prepareBeanFactory(beanFactory);
预处理BF,进行一些默认配置
预处理BF,进行一些默认配置
beanFactory.setBeanClassLoader(getClassLoader());
设置BF使用上下文的类加载器
设置BF使用上下文的类加载器
if (!shouldIgnoreSpel) {
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
如果没有忽略SpEL,设置SpEL作为默认的表达式解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
如果没有忽略SpEL,设置SpEL作为默认的表达式解析器
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
新增PropertyEditor
新增PropertyEditor
通过注册BeanPostProcessor,来处理这些接口的回调
ignoreDependencyInterface:自动装配时忽略给定的依赖接口,这通常用于AC来注册通过其他方式解析的依赖。
例如BF通过BeanFactoryAware,AC通过ApplicationContextAware。默认只有BeanFactoryAware接口被忽略。
ignoreDependencyInterface:自动装配时忽略给定的依赖接口,这通常用于AC来注册通过其他方式解析的依赖。
例如BF通过BeanFactoryAware,AC通过ApplicationContextAware。默认只有BeanFactoryAware接口被忽略。
registerResolvableDependency:注册一个特殊的依赖类型及其关联的自动装配值。这用于容器引用,它们可以被自动装配却没有在
工厂中定义为bean.
工厂中定义为bean.
通过注册BeanPostProcessor,来处理注册inner bean中的单例的ApplicationListener
探测加载时织入器,加载时织入可以通过在加载类字节码时更改字节码,来增强类的行为。
注册默认的环境bean:environment,systemProperties,systemEnvironment,applicationStartup
准备工作执行完毕,进入初始化阶段,try-catch
postProcessBeanFactory(beanFactory);
钩子方法,让子类注册BeanFactoryProcessor
钩子方法,让子类注册BeanFactoryProcessor
invokeBeanFactoryPostProcessors(beanFactory);
调用容器中注册的BeanFactoryPostProcessor。
BFPP执行时,所有的bean都加载了,但是没有初始化。
这允许BFPP可以在初始化bean前给bean更改或增加属性
调用容器中注册的BeanFactoryPostProcessor。
BFPP执行时,所有的bean都加载了,但是没有初始化。
这允许BFPP可以在初始化bean前给bean更改或增加属性
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
调用BFPP的postProcessBeanFactory方法。该方法中提到了两种BFPP:BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor。
后者是通常的BFPP,前者扩展了后者,多定义了方法postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry),它允许在执行下
一步postProcessBeanFactory之前对bean定义注册表进行操作,包括新增bean定义。
调用BFPP的postProcessBeanFactory方法。该方法中提到了两种BFPP:BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor。
后者是通常的BFPP,前者扩展了后者,多定义了方法postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry),它允许在执行下
一步postProcessBeanFactory之前对bean定义注册表进行操作,包括新增bean定义。
STEP 1
如果当前的BF实现了BeanDefinitionRegistry,那么需要额外处理BeanDefinitionRegistryPostProcessor
1. 处理AC传过来的beanFactoryPostProcessors,调用它们的postProcessBeanDefinitionRegistry方法
2. 处理BF中注册为Bean的BeanDefinitionRegistryPostProcessor
a. 处理匹配PriorityOrdered接口的,先排序再处理
b. 处理匹配Ordered接口的,先排序再处理
c. 处理其他的,由于在上述处理过程中可能向BF中注册了新的BDRPP,所以要不断地检查,直到没有新的BDRPP产生。
3. 调用所有BFPP(和BDRPP)的postProcessBeanFactory方法
如果当前的BF没有实现BeanDefinitionRegistry,那么直接处理AC传过来的beanFactoryPostProcessors
调用它们的postProcessBeanFactory方法
如果当前的BF实现了BeanDefinitionRegistry,那么需要额外处理BeanDefinitionRegistryPostProcessor
1. 处理AC传过来的beanFactoryPostProcessors,调用它们的postProcessBeanDefinitionRegistry方法
2. 处理BF中注册为Bean的BeanDefinitionRegistryPostProcessor
a. 处理匹配PriorityOrdered接口的,先排序再处理
b. 处理匹配Ordered接口的,先排序再处理
c. 处理其他的,由于在上述处理过程中可能向BF中注册了新的BDRPP,所以要不断地检查,直到没有新的BDRPP产生。
3. 调用所有BFPP(和BDRPP)的postProcessBeanFactory方法
如果当前的BF没有实现BeanDefinitionRegistry,那么直接处理AC传过来的beanFactoryPostProcessors
调用它们的postProcessBeanFactory方法
STEP 2
处理BF中注册为Bean的BFPP
a. 处理匹配PriorityOrdered接口的,先排序再处理,调用它们的postProcessBeanFactory方法
b. 处理匹配Ordered接口的,先排序再处理,调用它们的postProcessBeanFactory方法
c. 处理其他的,调用它们的postProcessBeanFactory方法
处理BF中注册为Bean的BFPP
a. 处理匹配PriorityOrdered接口的,先排序再处理,调用它们的postProcessBeanFactory方法
b. 处理匹配Ordered接口的,先排序再处理,调用它们的postProcessBeanFactory方法
c. 处理其他的,调用它们的postProcessBeanFactory方法
registerBeanPostProcessors(beanFactory);
将BPP注册到BF,便于在初始化Bean时对Bean进行处理
将BPP注册到BF,便于在初始化Bean时对Bean进行处理
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
将BPP注册到BF
将BPP注册到BF
处理BF中注册为Bean的BPP
1. 首先注册BeanPostProcessorChecker,用于打印日志
2. 注册匹配PriorityOrdered接口的,先排序再注册
3. 注册匹配Ordered接口的,先排序再注册
4. 注册其他BPP
5. 将实现了MergedBeanDefinitionPostProcessor的BPP重新注册,先排序再注册
6. 重新注册ApplicationListenerDetector
1. 首先注册BeanPostProcessorChecker,用于打印日志
2. 注册匹配PriorityOrdered接口的,先排序再注册
3. 注册匹配Ordered接口的,先排序再注册
4. 注册其他BPP
5. 将实现了MergedBeanDefinitionPostProcessor的BPP重新注册,先排序再注册
6. 重新注册ApplicationListenerDetector
重新注册会先移除,再注册,所以重新注册是为了保证BPP的执行顺序
initMessageSource();
注册messageSource,确保有messageSource存在
注册messageSource,确保有messageSource存在
initApplicationEventMulticaster();
注册applicationEventMulticaster,确保有applicationEventMulticaster存在
注册applicationEventMulticaster,确保有applicationEventMulticaster存在
onRefresh();
钩子方法,允许子类初始化其他特殊的Bean
钩子方法,允许子类初始化其他特殊的Bean
registerListeners();
注册监听器,并发布早期应用事件
注册监听器,并发布早期应用事件
1 将监听器注册到applicationEventMulticaster
AC中注册的监听器+BF中注册为bean的监听器ApplicationListener
2 将早期产生的事件交给applicationEventMulticaster处理
AC中注册的监听器+BF中注册为bean的监听器ApplicationListener
2 将早期产生的事件交给applicationEventMulticaster处理
finishBeanFactoryInitialization(beanFactory);
实例化所有剩余的(非延迟初始化)单例
实例化所有剩余的(非延迟初始化)单例
1 如果有则设置并初始化转换服务conversionService
2 如果BF中没有内置的valueResolver,设置默认的valueResolver
3 初始化LoadTimeWeaverAware bean使它们尽早注册transformer
4 不再使用临时的用于类型匹配的类加载器
5 锁定配置,不允许再对bean定义做修改
6 实例化所有剩余的(非延迟初始化)单例
2 如果BF中没有内置的valueResolver,设置默认的valueResolver
3 初始化LoadTimeWeaverAware bean使它们尽早注册transformer
4 不再使用临时的用于类型匹配的类加载器
5 锁定配置,不允许再对bean定义做修改
6 实例化所有剩余的(非延迟初始化)单例
beanFactory.preInstantiateSingletons();
AbstractBeanFactory#getBean
AbstractBeanFactory#doGetBean
DefaultSingletonBeanRegistry#getSingleton 三级缓存查找
DefaultSingletonBeanRegistry#getSingleton(String beanName, ObjectFactory<?> singletonFactory)
ObjectFactory#getObject
AbstractAutowireCapableBeanFactory#createBean
AbstractAutowireCapableBeanFactory#doCreateBean
AbstractAutowireCapableBeanFactory#createBeanInstance
AbstractAutowireCapableBeanFactory#addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); 暴露早期bean,解决环形依赖
AbstractAutowireCapableBeanFactory#populateBean
autowire -> getBean
AbstractAutowireCapableBeanFactory#initializeBean
DefaultSingletonBeanRegistry#addSingleton(beanName, singletonObject);
finishRefresh();
初始化LifecycleProcessor并调用它的onRefresh方法
发布ContextRefreshedEvent事件
初始化LifecycleProcessor并调用它的onRefresh方法
发布ContextRefreshedEvent事件
1 清除资源缓存
2 初始化lifecycleProcessor确保它存在
3 调用lifecycleProcessor的onRefresh方法
4 发布ContextRefreshedEvent
2 初始化lifecycleProcessor确保它存在
3 调用lifecycleProcessor的onRefresh方法
4 发布ContextRefreshedEvent
try结束,如果在上述过程中发生异常
destroyBeans();
销毁在BF中初始化的缓存单例
销毁在BF中初始化的缓存单例
cancelRefresh(ex);
重置active标志位false
重置active标志位false
进入finally
清除掉Spring中公共的内省缓存,
因为不再需要单例bean的元数据了
清除掉Spring中公共的内省缓存,
因为不再需要单例bean的元数据了
close
调用doClose,并移除不再需要的已注册的JVM shutdownHook
调用doClose,并移除不再需要的已注册的JVM shutdownHook
doClose
1 如果AC可用并且没有关闭,执行关闭操作
2 发布ContextClosedEvent事件
3 调用lifecycleProcessor的onClose方法
4 销毁在BF中初始化的缓存单例
5 调用onClose钩子方法,让子类执行一些清理工作
6 将监听器恢复到容器准备刷新的状态
7 将容器设置为未激活this.active.set(false);
2 发布ContextClosedEvent事件
3 调用lifecycleProcessor的onClose方法
4 销毁在BF中初始化的缓存单例
5 调用onClose钩子方法,让子类执行一些清理工作
6 将监听器恢复到容器准备刷新的状态
7 将容器设置为未激活this.active.set(false);
Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
DefaultListableBeanFactory
DefaultListableBeanFactory作为ApplicationContext的默认底层容器实现
继承父类和实现接口
AbstractAutowireCapableBeanFactory
#createBean
#createBean
AbstractBeanFactory
#doGetBean
#doGetBean
FactoryBeanRegistrySupport
支持用FactoryBean创建的单例注册
集成了父类DSBR的单例管理功能
支持用FactoryBean创建的单例注册
集成了父类DSBR的单例管理功能
DefaultSingletonBeanRegistry
#getSingleton 单例bean三级缓存。
使用ObjectFactory来解决环形依赖问题
#getSingleton 单例bean三级缓存。
使用ObjectFactory来解决环形依赖问题
SimpleAliasRegistry
使用ConcurentHashMap实现的别名注册表
别名 -> 规范名称。别名作为key不可以重复。
使用ConcurentHashMap实现的别名注册表
别名 -> 规范名称。别名作为key不可以重复。
AliasRegistry
定义别名的注册表
包含注册和获取bean的别名
定义别名的注册表
包含注册和获取bean的别名
SingletonBeanRegistry
定义共享单例bean的注册表
包含注册和获取单例bean等方法
定义共享单例bean的注册表
包含注册和获取单例bean等方法
ConfigurableBeanFactory
配置接口,提供配置BF的能力
配置接口,提供配置BF的能力
HierarchicalBeanFactory
BeanFactory
SingletonBeanRegistry
AutowireCapableBeanFactory
提供自动装配的能力
提供自动装配的能力
BeanFactory
ConfigurableListableBeanFactory
ListableBeanFactory...
AutowireCapableBeanFactory...
ConfigurableBeanFactory...
BeanDefinitionRegistry
AliasRegistry
Serializable
核心方法
preInstantiateSingletons
用来初始化容器中注册的单例bean
用来初始化容器中注册的单例bean
遍历bean定义,如果是单例且不是懒加载就调用getBean(String name)方法创建和初始化bean
AbstractBeanFactory#doGetBean
AbstractBeanFactory#doGetBean
1 解析bean的真名
去掉表示factoryBean的名称前缀&
通过别名注册表查询真名
去掉表示factoryBean的名称前缀&
通过别名注册表查询真名
2 查找缓存中是否包含该单例bean
DefaultSingletonBeanRegistry#getSingleton(String beanName)
DefaultSingletonBeanRegistry#getSingleton(String beanName)
三级缓存查找:singletonObjects里面是初始化完成的单例bean;earlySingletonObjects里面是正在创建,已实例化但未初始化的bean引用,用于解决环形依赖;singletonFactories用于获取earlySingleton的工厂,只使用一次,使用完成后就移除,将生成的对象放到二级缓存中。
3 如果返回的bean不为空
调用getObjectForBeanInstance取得bean实例
调用getObjectForBeanInstance取得bean实例
1 如果doGetBean传进来的名称标识了它是FactoryBean(&打头),并且返回的单例bean就是FB,那么直接返回
2 如果返回的bean不是FB,直接返回
3 先从由FBRS缓存中获取,若取到了就直接返回
FactoryBeanRegistrySupport#getCachedObjectForFactoryBean
FactoryBeanRegistrySupport#getCachedObjectForFactoryBean
4 若没有取到,就要通过FB创建
如果通过bean真名查找到了Bean定义,且Bean定义是合成的就不执行BPP
FactoryBeanRegistrySupport#getObjectFromFactoryBean
如果通过bean真名查找到了Bean定义,且Bean定义是合成的就不执行BPP
FactoryBeanRegistrySupport#getObjectFromFactoryBean
如果FB配置是单例的并且DefaultSingletonBeanRegistry缓存中已经存在了bean真名代表的单例
1 尝试从FBRS的缓存中取,取到了就返回
2 没有取到,就调用FB的getObject方法,再次检查FBRS的缓存
a 如果取到了,就代表在getObject方法调用过程中已经将该Bean加入了FBRS的缓存(在环形依赖的情况下会发生),返回从缓存中取到的值
b 如果没取到,就代表这是首次从该FB获取单例,根据方法参数条件判断是否执行BPP。
如果参数表示需要执行BPP
① 如果该bean真名代表的单例还在创建中,那么直接临时返回该对象。即不缓存也不执行BPP
② 先执行beforeSingletonCreation回调 -> 执行BPP(AbstractAutowireCapableBeanFactory#postProcessObjectFromFactoryBean) -> 执行afterSingletonCreation回调(为什么回调是包在执行BPP周围)
检查DSBR缓存中是否存在该bean真名,如果不存在就加入缓存(可能在执行getObject过程中移除了DSBR中的该bean)
1 尝试从FBRS的缓存中取,取到了就返回
2 没有取到,就调用FB的getObject方法,再次检查FBRS的缓存
a 如果取到了,就代表在getObject方法调用过程中已经将该Bean加入了FBRS的缓存(在环形依赖的情况下会发生),返回从缓存中取到的值
b 如果没取到,就代表这是首次从该FB获取单例,根据方法参数条件判断是否执行BPP。
如果参数表示需要执行BPP
① 如果该bean真名代表的单例还在创建中,那么直接临时返回该对象。即不缓存也不执行BPP
② 先执行beforeSingletonCreation回调 -> 执行BPP(AbstractAutowireCapableBeanFactory#postProcessObjectFromFactoryBean) -> 执行afterSingletonCreation回调(为什么回调是包在执行BPP周围)
检查DSBR缓存中是否存在该bean真名,如果不存在就加入缓存(可能在执行getObject过程中移除了DSBR中的该bean)
否则,就直接调用FB的getObject方法,再根据方法参数条件判断考虑是否执行BPP。
4 如果返回的bean为空
1 检查Bean定义是否存在,如果找不到且有父容器,则委托给父容器处理并返回
2 Bean定义在该容器存在
1 如果不只是为了检查类型,那么标记该bean真名为已创建
2 获取Bean定义中该bean的依赖bean,遍历它们
a 检查循环依赖,出现循环依赖报错
b 将依赖关系注册到dependentBeanMap和dependenciesForBeanMap
c 初始化依赖bean
a 检查循环依赖,出现循环依赖报错
b 将依赖关系注册到dependentBeanMap和dependenciesForBeanMap
c 初始化依赖bean
3 如果Bean定义配置为单例,创建bean实例
DefaultSingletonBeanRegistry#getSingleton(String beanName, ObjectFactory<?> singletonFactory)
DefaultSingletonBeanRegistry#getSingleton(String beanName, ObjectFactory<?> singletonFactory)
1 检查singletonObjects缓存中是否存在该bean,若存在直接返回
2 不存在,则准备创建。beforeSingletonCreation回调 -> 调用ObjectFactory#getObject -> afterSingletonCreation回调
这里传入的ObjectFactory是一个匿名内部类,里面调用了AbstractAutowireCapableBeanFactory#createBean实现
createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
1 调用resolveBeforeInstantiation 给BeanPostProccessors一个机会返回一个代理实例而不是目标bean实例
得到的返回值不为null则直接返回。只调用InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation来尝试创建bean,
创建成功之后,会应用所有的BPP的postProcessAfterInstantiation
得到的返回值不为null则直接返回。只调用InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation来尝试创建bean,
创建成功之后,会应用所有的BPP的postProcessAfterInstantiation
2 调用doCreateBean
createBeanInstance
创建Bean实例,并使用BeanWrapper包装
创建Bean实例,并使用BeanWrapper包装
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
尝试从supplier获取Bean实例
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
尝试从supplier获取Bean实例
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
尝试从工厂方法获取Bean实例
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
尝试从工厂方法获取Bean实例
尝试用合适的构造器构造实例
applyMergedBeanDefinitionPostProcessors
遍历调用MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
允许在设置属性前,修改bean定义
遍历调用MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
允许在设置属性前,修改bean定义
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
如果允许环形引用,则注册单例工厂到DSBR第三级缓存
如果允许环形引用,则注册单例工厂到DSBR第三级缓存
populateBean(beanName, mbd, instanceWrapper);
遍历执行InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation。在调用工厂方法或构造器初始化bean之后,在设置属性之前的扩展点。
执行自动装配,将装配结果放到PropertyValues中,后面就是来操作它了
遍历执行InstantiationAwareBeanPostProcessor#postProcessProperties
依赖检查
类型转换以适配属性类型,之后将操作后的属性值设置到实例中,完成bean装配
initializeBean(beanName, exposedObject, mbd);
invokeAwareMethods(beanName, bean);
BeanPostProcessor#postProcessBeforeInitialization
invokeInitMethods(beanName, wrappedBean, mbd);
((InitializingBean) bean).afterPropertiesSet()
invokeCustomInitMethod(beanName, bean, mbd)
BeanPostProcessor#postProcessAfterInitialization
3 如果是通过getObject方法创建的新单例,那么将单例放到singletonObjects缓存中。
场景问题
Spring如何解决环形依赖
Spring使用三级缓存来解决环形依赖,三级缓存在DefaultSingletonBeanRegistry中,它们是三个map
singletonObjects:里面存放的是初始化完成的Bean
earlySingletonObjects:里面存放着通过singletonFactories调用getBean返回的结果
singletonFactories:里面存放着仅用于获取earlySingleton的工厂ObjectFactory,当发生环形依赖时,就会通过该工厂调用一次getObject获取尚未完全装配完成的Bean。调用完成后,将尚未初始化完成的返回对象放到earlySingletons二级缓存中,而该ObjectFactory将从三级缓存中移除
解决方案不支持
构造器注入循环依赖
prototype模式field属性注入循环依赖
可参考文章:https://blog.csdn.net/fedorafrog/article/details/104550165
收藏
收藏
0 条评论
下一页