网站开发所需配置jsp网站开发 pdf
- 作者: 五速梦信息网
- 时间: 2026年03月21日 07:34
当前位置: 首页 > news >正文
网站开发所需配置,jsp网站开发 pdf,网站建设优惠券,网站设计平台 动易SpringBoot扩展篇#xff1a;循环依赖源码链路 1. 相关文章2. 一个简单的Demo3. 流程图3.1 BeanDefinition的注册3.2 开始创建Bean3.3 从三级缓存获取Bean3.4 创建Bean3.5 实例化Bean3.6 添加三级缓存3.7 属性初始化3.8 B的创建过程3.9 最终流程 1. 相关文章 SpringBoot 源码… SpringBoot扩展篇循环依赖源码链路 1. 相关文章2. 一个简单的Demo3. 流程图3.1 BeanDefinition的注册3.2 开始创建Bean3.3 从三级缓存获取Bean3.4 创建Bean3.5 实例化Bean3.6 添加三级缓存3.7 属性初始化3.8 B的创建过程3.9 最终流程 1. 相关文章 SpringBoot 源码解析全集 SpringBoot 源码解析5ConfigurationClassPostProcessor整体流程和ComponentScan源码分析 SpringBoot 源码解析6Bean的创建① AbstractBeanFactory#doGetBean SpringBoot 源码解析7Bean的创建② AbstractAutowireCapableBeanFactory#createBean SpringBoot扩展篇Spring注入 Autowired Resource 在Spring中注册BeanDefinition和实例化bean的流程是分开的。 在bean实例化之前Spring已经将所有要实例化的Bean的信息封装成BeanDefinition 并且注册到DefaultListableBeanFactory#beanDefinitionMap。本文只是循环依赖原理总结和相关代码链路想要真正读懂循环依赖源码需要一定的内功心法详细的源码解析在上面链接中。
- 一个简单的Demo Component public class ObjectA {Autowiredprivate ObjectB objectB;}Component public class ObjectB {Autowiredprivate ObjectA objectA;}这是一个简单的循环依赖Demo后续的讲解以Demo为例。ObjectA、ObjectB 简称AB。
- 流程图 这是作者照着源码一步一步Debug画出的流程图下面的Step序号与流程图中序号一致挑重点讲。
3.1 BeanDefinition的注册
Step1在实例化之前Spring将要创建的Bean所对应的BeanDefinition都注册到BeanFactory。 参考SpringBoot 源码解析5ConfigurationClassPostProcessor整体流程和ComponentScan源码分析
3.2 开始创建Bean
Step2在此之前所有的BeanDifinition全部注册到bean工厂。
Override public void preInstantiateSingletons() throws BeansException {if (logger.isTraceEnabled()) {logger.trace(Pre-instantiating singletons in this);}// Iterate over a copy to allow for init methods which in turn register new bean definitions.// While this may not be part of the regular factory bootstrap, it does otherwise work fine.ListString beanNames new ArrayList(this.beanDefinitionNames);// Trigger initialization of all non-lazy singleton beans…for (String beanName : beanNames) {RootBeanDefinition bd getMergedLocalBeanDefinition(beanName);if (!bd.isAbstract() bd.isSingleton() !bd.isLazyInit()) {if (isFactoryBean(beanName)) {Object bean getBean(FACTORY_BEAN_PREFIX beanName);if (bean instanceof FactoryBean) {final FactoryBean? factory (FactoryBean?) bean;boolean isEagerInit;if (System.getSecurityManager() ! null factory instanceof SmartFactoryBean) {isEagerInit AccessController.doPrivileged((PrivilegedActionBoolean)((SmartFactoryBean?) factory)::isEagerInit,getAccessControlContext());}else {isEagerInit (factory instanceof SmartFactoryBean ((SmartFactoryBean?) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}}else {getBean(beanName);}}}// Trigger post-initialization callback for all applicable beans…for (String beanName : beanNames) {Object singletonInstance getSingleton(beanName);if (singletonInstance instanceof SmartInitializingSingleton) {final SmartInitializingSingleton smartSingleton (SmartInitializingSingleton) singletonInstance;if (System.getSecurityManager() ! null) {AccessController.doPrivileged((PrivilegedActionObject) () - {smartSingleton.afterSingletonsInstantiated();return null;}, getAccessControlContext());}else {smartSingleton.afterSingletonsInstantiated();}}} }在refresh方法中会调用DefaultListableBeanFactory#preInstantiateSingletons遍历所有的beanName调用getBean方法获取Bean。 3.3 从三级缓存获取Bean protected Object getSingleton(String beanName, boolean allowEarlyReference) {Object singletonObject this.singletonObjects.get(beanName);if (singletonObject null isSingletonCurrentlyInCreation(beanName)) {synchronized (this.singletonObjects) {singletonObject this.earlySingletonObjects.get(beanName);if (singletonObject null allowEarlyReference) {ObjectFactory? singletonFactory this.singletonFactories.get(beanName);if (singletonFactory ! null) {singletonObject singletonFactory.getObject();this.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);}}}}return singletonObject; }singletonObjects一级缓存 earlySingletonObjects 二级缓存 singletonFactory三级缓存从三级缓存中获取Bean时会调用singletonFactory.getObject()。 从缓存中逐级获取如果缓存中找到了对应的Bean那么就会返回beangetBean方法调用结束。否则就会创建Bean放入缓存然后返回bean。 3.4 创建Bean doCreateBean方法
singletonFactory是一个函数式接口会回调CreateBean方法创建Bean。 //AbstractBeanFactory#doGetBean if (mbd.isSingleton()) {sharedInstance getSingleton(beanName, () - {try {return createBean(beanName, mbd, args);}catch (BeansException ex) {// Explicitly remove instance from singleton cache: It might have been put there// eagerly by the creation process, to allow for circular reference resolution.// Also remove any beans that received a temporary reference to the bean.destroySingleton(beanName);throw ex;}});bean getObjectForBeanInstance(sharedInstance, name, beanName, mbd); }当创建完成单例Bean最终会放入到一级缓存中。对应Step21和Step24先放入的B在放入的A。 protected void addSingleton(String beanName, Object singletonObject) {synchronized (this.singletonObjects) {this.singletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);this.earlySingletonObjects.remove(beanName);this.registeredSingletons.add(beanName);} }3.5 实例化Bean Step7createBeanInstance Spring中兼容了自定义Supplier创建、Configuration注解的工厂创建、构造器创建等多种创建方式。 3.6 添加三级缓存 Step8放入到三级缓存singletonObjects中此时的A只是对象创建成功属性还未开始赋值。 boolean earlySingletonExposure (mbd.isSingleton() this.allowCircularReferences isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) {if (logger.isTraceEnabled()) {logger.trace(Eagerly caching bean beanName to allow for resolving potential circular references);}addSingletonFactory(beanName, () - getEarlyBeanReference(beanName, mbd, bean)); }protected void addSingletonFactory(String beanName, ObjectFactory? singletonFactory) {Assert.notNull(singletonFactory, Singleton factory must not be null);synchronized (this.singletonObjects) {if (!this.singletonObjects.containsKey(beanName)) {this.singletonFactories.put(beanName, singletonFactory);this.earlySingletonObjects.remove(beanName);this.registeredSingletons.add(beanName);}} }一个bean只会缓存在一个缓存中在加入到一个缓存的时候会移除其他两个缓存。 FunctionalInterface public interface ObjectFactoryT {/*** Return an instance (possibly shared or independent)* of the object managed by this factory.* return the resulting instance* throws BeansException in case of creation errors*/T getObject() throws BeansException;}可以看到三级缓存中存放的是ObjectFactory函数式接口。 我们可以看到如果当前bean被代理了那么就会在AbstractAutoProxyCreator中缓存了当前bean对应的代理bean那么三级缓存会返回代理bean否则就会返回当前bean。 3.7 属性初始化 初始化逻辑可参考SpringBoot扩展篇Spring注入 Autowired Resource 最终会回调getBean方法参数为A对象依赖bean的名称。此时第二次调用getBean方法 3.8 B的创建过程 B的创建会重复3.3-3.7流程发现B也依赖A。就会第三次调用getBean方法。 3.9 最终流程 第三次调用getBean方法获取A但是此时的A已经缓存在singletonFactory中在调用getSingleton的时候会将A从singletonFactory中取出来放入到二级缓存earlySingletonObjects中。第三次getBean方法就会返回A对B对象的A属性赋值。当B对象的所有属性赋值完毕之后会调用addSingleton将B放入到一级缓存中。此时的B是最终成品。第二次getBean方法返回B对象对A对象的B属性赋值。当A对象的所有属性赋值完毕之后会调用addSingleton将A放入到一级缓存中。此时的A是最终成品。第一次调用getBean方法返回A对象。流程结束
- 上一篇: 网站开发算前端吗怎么做网站备案连接
- 下一篇: 网站开发所需要的书籍官方网站下载微信
相关文章
-
网站开发算前端吗怎么做网站备案连接
网站开发算前端吗怎么做网站备案连接
- 技术栈
- 2026年03月21日
-
网站开发四点注意事项网站开发设计各部门职责
网站开发四点注意事项网站开发设计各部门职责
- 技术栈
- 2026年03月21日
-
网站开发税率灵雀云 wordpress
网站开发税率灵雀云 wordpress
- 技术栈
- 2026年03月21日
-
网站开发所需要的书籍官方网站下载微信
网站开发所需要的书籍官方网站下载微信
- 技术栈
- 2026年03月21日
-
网站开发所要达到的目标广州本地做网站
网站开发所要达到的目标广州本地做网站
- 技术栈
- 2026年03月21日
-
网站开发所要达到的目标网站备案都审核什么资料
网站开发所要达到的目标网站备案都审核什么资料
- 技术栈
- 2026年03月21日
