- prepareRefresh() spring 版本 5.1.5.RELEASE
准备刷新的工作
1 | protected void prepareRefresh() { |
- obtainFreshBeanFactory()
获取Bean工厂
1 | protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { |
- prepareBeanFactory(beanFactory)
准备Bean工厂
1 | protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { |
- postProcessBeanFactory(beanFactory) 自定义后置处理
- invokeBeanFactoryPostProcessors(beanFactory)
处理BeanFactoryPostProcessor后置处理器
org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
1 | public static void invokeBeanFactoryPostProcessors( |
- registerBeanPostProcessors(beanFactory)
注册BeanPostProcessors处理器
org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors
1 | public static void registerBeanPostProcessors( |
initMessageSource() 国际化
initApplicationEventMulticaster() 初始化ApplicationEventMultimaster
onRefresh() 模板方法,可以在单例实例化之前调用
registerListeners() 注册监听器,只是将监听器信息保存到 ApplicationEventMulticaster类的相应集合中
finishBeanFactoryInitialization(beanFactory)
加载非懒加载的对象
1 | protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { |
finishRefresh()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
// Initialize lifecycle processor for this context.
// 初始化LifecycleProcessor
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// Publish the final event.
// 广播发布事件
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
// spring.liveBeansView.mbeanDomain
// 可以远程修改bean? https://www.freesion.com/article/6709600928/
LiveBeansView.registerApplicationContext(this);
}resetCommonCaches() 清理缓存
补充获取Bean的方法
org.springframework.beans.factory.support.AbstractBeanFactory#getBean
1 | protected <T> T doGetBean(final String name, final Class<T> requiredType, |
如果是单例模式,则获取单例对象:
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton
1 | public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { |
工厂创建对象的方法
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean
1 | protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) |
创建对象的方法
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
1 | protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) |
创建Bean实例
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
1 | protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args){ |
属性注入
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
1 | protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw){ |
初始化Bean。 调用 invokeAwareMethods-> 前置处理器>Bean的init方法>后置处理器
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean
1 | protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { |
- 补充 org.springframework.context.annotation.ConfigurationClassPostProcessor
org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions
1 | public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { |
1 | public void parse(Set<BeanDefinitionHolder> configCandidates) { |
- 循环依赖
为了测试,我创建了两个类,TestBeanA、TestBeanB。我们前面已经说过了@Component标注的类,将有
ConfigurationClassPostProcessor 类扫描并放到BeanDefinition集合中,所以我们直接跳到spring的 refresh 方法里面的 finishBeanFactoryInitialization(beanFactory) 方法,点进此方法之后,看此方法里面的最后一个方法 beanFactory.preInstantiateSingletons(),这才是重点。
1 |
|
1 | public void preInstantiateSingletons() throws BeansException { |
也就是 AutowiredAnnotationBeanPostProcessor,该类的postProcessProperties方法会处理我们对象变量或对象方法上的 @Autowired注解
1 | public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) { |
那三级缓存处理循环依赖就是这样的。首先通过默认构造器(我这里调试是这样,其实有很多种版本方式),创建出TestBeanA对象,然后将创建对象以工厂的方式缓存到singletonFactories(第三级缓存)中。然后进行属性赋值操作,即populateBean方法,当碰到注入的属性是对象TestBeanB时(我使用的是@Autowired注解,会由 AutowiredAnnotationBeanPostProcessor处理器去加载并注入),那么他还是会调用获取Bean的方法,以此来获取TestBeanA,因为我们已经将TestBeanA以工厂的方式放入到了singletonFactories中,所以直接获取,并将对象放到earlySingletonObjects缓存中。那么我之前有一个疑问,不知道earlySingletonObjects的作用是啥。
我们注意org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean会有下面的代码,即在完全实例化完对象之后,如果earlySingletonExposure为true会从二级缓存拿出对象。我猜想有一种可能,我们在看一下三级缓存中保存的ObjectFactory代码,即getEarlyBeanReference方法(就在代码的上面)。
这块的代码会在实例化TestBeanB的时候调用,这里返回的Object可能是一个代理对象。我们注意实例化TestBeanB的时候,是处于TestBeanA属性初始化的时候,所以TestBeanA还需要回来执行完populateBean和exposedObject方法,但操作的是原始对象,为了保证与TestBeanB初始化时(TestBeanB依赖TestBeanA)获取的TestBeanA对象是一个(担心调用工厂接口的时候,会生成一个代理对象),所以这里需要在重新判断获取一下。
至于为什么代理对象在创建完对象之后,这个要问Spring了。
20240627对于Spring解决循环依赖的补充:
问题:为啥非得三级缓存,二级缓存不行吗?
答:首先只是我的个人理解。其实二级缓存也够用了。TestBeanB通过属性注入获取TestBeanA对象时,可以直接从缓存中获取值是没问题的。但这里Spring设计了一个可以提前获取TestBeanA的代理对象。
那如果TestBeanB属性注入去获取TestBeanA对象时,此时TestBeanA位于二级缓存(假设只有二级缓存),并且返回了一个代理对象,注意TestBeanB注入的对象为代理对象。此时返回TestBeanA的populateBean属性注入方法调用处,TestBeanA任然是源对象,此时已经产生了两个不同的对象了,违背了单例的规则。这也就是为什么底下的代码要从二级缓存中重新获取一下对象,因为可能代理对象被放在了二级缓存中。
其实二级缓存也就够用了,三级缓存的设计可能只是想早点获取一个代理类或与调用源头不一样的类。至于为什么要这样设计,这个要问Spring了。
1 | if (earlySingletonExposure) { |