spring 实例化单例bean
2022-02-21 15:22:19 0 举报
spring 实例化整体流程图
作者其他创作
大纲/内容
不是FactoryBean
// 子BeanDefinition的属性覆盖父BeanDefinition的属性,这就是合并\t\t\t\t\tmbd = new RootBeanDefinition(pbd);\t\t\t\t\tmbd.overrideFrom(bd);
遍历所有beanName(扫描过程中加入到缓存中的)
不是null
需要A
单例池中存在
// 不存在就去合并
if (!(beanInstance instanceof FactoryBean))
不存在就去创建
dependsOn != null是不是有@DependsOn
mbd.isPrototype()原型
mergedBeanDefinitions
parentBeanFactory != null && !containsBeanDefinition(beanName)
从singletonFactories根据beanName得到一个ObjectFactory,然后执行ObjectFactory,也就是执行getEarlyBeanReference方法,此时会得到一个A原始对象经过AOP之后的代理对象,然后把该代理对象放入earlySingletonObjects中,注意此时并没有把代理对象放入singletonObjects中,那什么时候放入到singletonObjects中呢?我们这个时候得来理解一下earlySingletonObjects的作用,此时,我们只得到了A原始对象的代理对象,这个对象还不完整,因为A原始对象还没有进行属性填充,所以此时不能直接把A的代理对象放入singletonObjects中,所以只能把代理对象放入earlySingletonObjects,假设现在有其他对象依赖了A,那么则可以从earlySingletonObjects中得到A原始对象的代理对象了,并且是A的同一个代理对象。当B创建完了之后,A继续进行生命周期,而A在完成属性注入后,会按照它本身的逻辑去进行AOP,而此时我们知道A原始对象已经经历过了AOP,所以对于A本身而言,不会再去进行AOP了,那么怎么判断一个对象是否经历过了AOP呢?会利用上文提到的earlyProxyReferences,在AbstractAutoProxyCreator的postProcessAfterInitialization方法中,会去判断当前beanName是否在earlyProxyReferences,如果在则表示已经提前进行过AOP了,无需再次进行AOP。对于A而言,进行了AOP的判断后,以及BeanPostProcessor的执行之后,就需要把A对应的对象放入singletonObjects中了,但是我们知道,应该是要把A的代理对象放入singletonObjects中,所以此时需要从earlySingletonObjects中得到代理对象,然后入singletonObjects中。
先从缓存中拿object = getCachedObjectForFactoryBean(beanName)
加入
从缓存中去取
首先发布ContextClosedEvent事件调用lifecycleProcessor的onCloese()方法销毁单例Bean遍历disposableBeans把每个disposableBean从单例池中移除调用disposableBean的destroy()如果这个disposableBean还被其他Bean依赖了,那么也得销毁其他Bean如果这个disposableBean还包含了inner beans,将这些Bean从单例池中移除掉 (inner bean参考https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-inner-beans)清空manualSingletonNames,是一个Set,存的是用户手动注册的单例Bean的beanName清空allBeanNamesByType,是一个Map,key是bean类型,value是该类型所有的beanName数组清空singletonBeanNamesByType,和allBeanNamesByType类似,只不过只存了单例Bean
缓存有
是null
不是抽象的
singletonFactories三级缓存
不存在循环依赖
将B赋值给A
那么就直接返回当前传入的对象
遍历依赖的DependsOn
//其实MethodOverrides的作用就是在spring配置中存在lookup-mehtod和replace-method的, // 而这两个配置在加载xml的时候就会统一存放在BeanDefinition中的methodOverrides属性里。 //遍历MethodOverrides, // 对于一个方法的匹配来讲, // 如果一个类中存在若干个重载方法,那么,在函数调用以及增强的时候还需要根据参数类型进行匹配, // 来最终确认当前调用的到底是哪个函数,但是,spring将一部分匹配工作在这里完成了,如果当前类中的方法只有一个, // 那么就设置重载该方法没有被重载,这样在后续调用的时候便可以直接使用找到的方法,而不需要进行方法的参数匹配了, // 而且还可以提前对方法存在性进行验证。 mbdToUse.prepareMethodOverrides();
不成立
该beanDefinition 存在父节点
// <bean id=\"orderService\" class=\"com.zhouyu.service.OrderService\" scope=\"prototype\" abstract=\"true\"/>\t\t\t// abstract=\"true\" 判断 不是抽象BeanDefinition && 是单例 && 不是懒加载\t\t\tif (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit())
是FactoryBean
不存在
// 实例化非懒加载的单例Bean beanFactory.preInstantiateSingletons();
执行lambda
// 创建Bean对象\t\t\t\t\tgetBean(beanName)
放入缓存
// 将beanDefinition 重新构造成 RootBeanDefinition
存在
A创建完成
父节点是否也有父节点
从earlySingletonObjects中得到代理对象,然后放入singletonObjects单例池中
return beanInstance;
该beanDefinition 不存在父节点
if (isFactoryBean(beanName))// 判断是否是FactoryBean 就是该类是否实现了 FactoryBean 接口
与springMvc 相关的作用域例如@SessionScope
return 执行重写的object()后的方法
mbd.isSingleton()单例
返回值不是null
markBeanAsCreated(beanName)标记bean正在被构建
单例放入缓存
放入单例池
//单例池查找逻辑与循环依赖解决
AbstractApplicationContext将单例非懒加载bean 实例化放入单例池finishBeanFactoryInitialization(beanFactory)
return parentBeanFactory).doGetBean
判断是不是实现了SmartFactoryBean并重写了 isEagerInit()方法
hasInstantiationAwareBeanPostProcessors()// 判断缓存中是否存在实现了InstantiationAwareBeanPostProcessor 接口的bean
传入的对象是factoryBean
createBean
earlySingletonObjects二级缓存
sharedInstance != null && args == nullObject sharedInstance = getSingleton(beanName);
否
不是
B创建完成
返回值是不是null
是
单例A在创建时
根据传入的name 找到对应缓存中的名字
先创建当前依赖的对象
if(bd.getParentName() == null)
满足条件
没有返回null
object == null
先从.mergedBeanDefinitions缓存池里找
SingletonMap
传入的对象不是FactoryBean,则直接返回
这个ObjectFactory就是上文说的labmda表达式,中间有getEarlyBeanReference方法,注意存入singletonFactories时并不会执行lambda表达式,也就是不会执行getEarlyBeanReference方法
!mbd.isSynthetic()是不是合成bean
最后返回值true
缓存没有
if (BeanFactoryUtils.isFactoryDereference(name))
当前Bean是否实现了DisposableBean接口或者,当前Bean是否实现了AutoCloseable接口BeanDefinition中是否指定了destroyMethod调用DestructionAwareBeanPostProcessor.requiresDestruction(bean)进行判断ApplicationListenerDetector中直接使得ApplicationListener是DisposableBeanInitDestroyAnnotationBeanPostProcessor中使得拥有@PreDestroy注解了的方法就是DisposableBean把符合上述任意一个条件的Bean适配成DisposableBeanAdapter对象,并存入disposableBeans中(一个LinkedHashMap)
true--// 创建真正的Bean对象(getObject()返回的对象)
加入缓存
InitDestroyAnnotationBeanPostProcessor
return bean;结束
单例B去创建
// 获取合并后的BeanDefinition RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
pbd = getMergedBeanDefinition(parentBeanName)先父节点合并
factoryBeanObjectCache
postProcessBeforeInstantiation()方法有没有返回值
return exposedObject;
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName)
存在并且不需要重新合并mbd != null && !mbd.stale
成立
if (bean != null)
if (isEagerInit)(默认是false)
属性填充需要 单例B
getBean(\"&\" + beanName)获取FactoryBean 本身
// name有可能是 &xxx 或者 xxx,如果name是&xxx,那么beanName就是xxx // name有可能传入进来的是别名,那么beanName就是id String beanName = transformedBeanName(name);
判断bean是否定义了init-method
0 条评论
回复 删除
下一页