记录并分享一下本人学习spring源码的过程,有什么问题或者补充会持续更新。欢迎大家指正!
环境: spring5.X + idea
建议:学习过程中要开着源码一步一步过
Spring中对象的创建宏观流程:
在BeanFactory中getBean时做一下三步处理完成对象的创建
doCreateBean
createBeanInstance(beanName, mbd, args);
doCreateBean
populateBean(beanName, mbd, instanceWrapper);这里属性赋值也就是注入分为多种方式
<bean autowired= "bytype|byname"/> <beans default-autowired="bytype|byname"/>b. 注解 @Autowired
doCreateBean
initializeBean(beanName, exposedObject, mbd);在初始化的过程中细分了几个部分分别是
宏观流程了解清楚了之后,先分析一下createBean之前spring做了那些事,也就是Beanfactory调用
doGetBean
然后执行createbean
调用AbstractAutowireCapableBeanFactory中的doCreateBean
之前Spring还做了什么样的处理
上源码(createbean执行之前)
String beanName = this.transformedBeanName(name); Object sharedInstance = this.getSingleton(beanName); Object bean; if(sharedInstance != null && args == null) { //日志打印的 bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null); } else { }
源码说明:else 之前就是创建对象之前做的一些事情
说明
:从这个方法的命名就可以知道他是用来转化对象对象名的,Spring配置Bean的时候可以写id,name,别名,这里就是把这些转换成这个对象的唯一id供后续使用。说明
:从单例池中获取对象,然后判断是否获取到对应的对象,如果没有获取到就执行else去创建,如果获取到了Spring又做了一个普通对象还是实现了FactoryBean接口的对象,getObjectForBeanInstance,如果是普通对象直接返回,如果是实现了FactoryBean接口对象就会调用getObject方法返回。三级缓存
:单例池最根本的实现是Spring设计了一个三级缓存,也就是DefaultSingletonBeanRegistry中的三个Map
singletonObjects
一级缓存earlySingletonObjects
二级缓存singletonFactories
三级缓存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; }
说明
:如果存在父子工厂,那么他们的配置会融合,发现同名配置会优先使用子工厂中的配置BeanFactory parentBeanFactory = this.getParentBeanFactory(); if(parentBeanFactory != null && !this.containsBeanDefinition(beanName)) { String nameToLookup = this.originalBeanName(name); if(parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly); } if(args != null) { return parentBeanFactory.getBean(nameToLookup, args); } if(requiredType != null) { return parentBeanFactory.getBean(nameToLookup, requiredType); } return parentBeanFactory.getBean(nameToLookup); }
说明
:获取父类工厂,如果存在父工厂并且子工厂中没有对应的BeanDefinition就从父工厂中递归查找,然后实例化对应的对象。如果父工厂中也没有找到当前的这个对象那就是自己创建,调用createBean
到doCreateBean
中执行创建对象的那几步。感谢您的阅读,有什么意见和问题欢迎评论区留言!书写不易!
觉得文章对你有帮助记得给我点个赞,欢迎大家关注和转发文章!