前言:疫情期间,在家办公,虽说有种种不便,与此同时,也有了充足的时间,学习了一些想学习的知识,如有错误,敬请指出。
1:解读
spring的主要功能是IOC与AOP,此章节暂时不讲述AOP,但针对IOC来讲,getBean()方法是重中之重,例如下面这个例子,我们这样做就可以从容器中取出一个bean的实例
AnnotationConfigApplicationContext configApplicationContext=new AnnotationConfigApplicationContext(ProductServiceApplication.class);
configApplicationContext.getBean("test");
在整个spring源码之中,new AnnotationConfigApplicationContext(ProductServiceApplication.class)可以说初始化方法占据了极大的一部分,今天,不讲述初始化的过程,单纯从源码角度讲述getBean的工作流程
2:调用链说明
AnnotationConfigApplicationContext.getBean-->AbstractBeanFactory.getBean-->AbstractBeanFactory.doGetBean-->AbstractBeanFactory.getSingleton-->AbstractBeanFactory.createBean
上面是主要的流程,可以看出,getBean的真正获取,是在BeanFactory里面实现的,只不过AnnotationConfigContext里面有bean工厂的实例,最终的bean的创建是在beanFactory里面完成的
spring的方法命名规范也很有意思,几个getBean的方法其实没有做什么事情,最终是在doGetBean和getSignleton与createBean里面完成的。因此,代码解析在doGetBean(AbstractBeanFactory)开始。(由于电脑原因,down下来的spring源码已经丢了,只能看反编译过的代码,出入不大)
3:doGetBean解析
protected <T> T doGetBean(String name, Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
//获取bean的名称(因为存在FactoryBean,以后的博客再讲)
final String beanName = this.transformedBeanName(name);
//缓存,如果单例池中有的话就从单例池中获取,没有的话再创建,这个方法重要,解决循环依赖也是在这操作的
Object sharedInstance = this.getSingleton(beanName);
Object bean;
if (sharedInstance != null && args == null) {
//如果缓存池中存在
if (this.logger.isDebugEnabled()) {
if (this.isSingletonCurrentlyInCreation(beanName)) {
this.logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
} else {
this.logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
}
if (!typeCheckOnly) {
this.markBeanAsCreated(beanName);
}
try {
final RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
this.checkMergedBeanDefinition(mbd, beanName, args);
//又是一个重要的代码
if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
try {
return AbstractBeanFactory.this.createBean(beanName, mbd, args);
} catch (BeansException var2) {
AbstractBeanFactory.this.destroySingleton(beanName);
throw var2;
}
}
});
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
}
与流程无关的代码已经被我删减了,可以看这些重要的代码。
(1):final String beanName = this.transformedBeanName(name);这主要是获取bean的一个名称,这么解释可能有些人有疑问了,不是我们getBean的时候已经把bean的名称传递进来了么,这么做的原因是因为存在一种特殊的bean(FactoryBean),之后会单开一讲专门讲解这个(很重要,一些三方框架例如mybatis与spring整合的时候就用到这个了)
(2):Object sharedInstance = this.getSingleton(beanName);主要是从单例池中获取bean,因为我们getBean获取的事单例模式的,所以假设我们之前创建过的时候不会重复创建,直接在单例池中取出来返回,而且这也是spring解决循环依赖的重要部分(不懂什么叫循环依赖的同学自行百度)
看下这块的代码逻辑
public Object getSingleton(String beanName) {
return this.getSingleton(beanName, true);
}
//参数allowEarlyReference的意思是是否允许提前创建,spring解决循环依赖就是通过允许提前创建一个实例来解决的
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//singletonObjects单例池对象,存储单例对象的一个map
Object singletonObject = this.singletonObjects.get(beanName);
//如果单例池中不存在&并且这个对象正在创建
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
synchronized(this.singletonObjects) {
//earlySingletonObjects(提前创建的bean的单例池)
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//还是空,beanFactory.getBean方法获取
singletonObject = singletonFactory.getObject();
//放入提前创建的单例池中
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject != NULL_OBJECT ? singletonObject : null;
}
getSignleton()方法的主要功能是看单例池中是否存在这个对象,存在返回,不存在则继续进行(关于earlySingletonObjects与singletonFactory可以暂时不用关注,结合后面内容一起理解)
(3):getSignleton(String beanName,ObjectFactory objectFacorty)注意区别下上面的getSingle方法,这里进入了BeanFactory真正创建单例对象的过程
sharedInstance = this.getSingleton(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
try {
//这里是获取一个FactoryBean对象
return AbstractBeanFactory.this.createBean(beanName, mbd, args);
} catch (BeansException var2) {
AbstractBeanFactory.this.destroySingleton(beanName);
throw var2;
}
}
});
这其中应用到了好多后置处理器的地方,暂时不进行讲解,后面会抽时间呐出专门的篇章进行介绍后置处理器(Spring AOP功能就是利用后置处理器完成的)
进入getSignleton(beanName,FactoryBean factoryBean)方法内部
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "'beanName' must not be null");
synchronized(this.singletonObjects) {
//同样,先从缓存池中获取,没有再创建
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (this.logger.isDebugEnabled()) {
this.logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
//将这个beanName加入singletonsCurrentlyInCreation集合里面(代表正在创建此对象)
this.beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = this.suppressedExceptions == null;
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet();
}
try {
//调用刚刚说的自己创建的FactoryBean进行创建对象
singletonObject = singletonFactory.getObject();
newSingleton = true;
} catch (IllegalStateException var16) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw var16;
}
} catch (BeanCreationException var17) {
BeanCreationException ex = var17;
if (recordSuppressedExceptions) {
Iterator var8 = this.suppressedExceptions.iterator();
while(var8.hasNext()) {
Exception suppressedException = (Exception)var8.next();
ex.addRelatedCause(suppressedException);
}
}
throw ex;
} finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
//不用关注,校验
this.afterSingletonCreation(beanName);
}
if (newSingleton) {
//如果是第一次创建这个对象,需要把这个对象加入到singletonObjects单例池,并且从singletonFactories与earlySingletonObjects移除他,这两个map的作用会在循环依赖中讲到
this.addSingleton(beanName, singletonObject);
}
}
return singletonObject != NULL_OBJECT ? singletonObject : null;
}
}
总结下getSignleton(beanName,FactoryBean factoryBean)方法
【1】:单例缓存池中没有的话再创建
【2】:调用传进来的FactoryBean的getBean方法获取对象
【3】:创建末尾,将创建好的对象加入单例池,并且从singletonFactories与earlySinletonObjects中移除这个beanName。
重点关注【2】,我们在调用这个方法的时候自己创建了一个beanFactory并且,因此,创建的主要逻辑就在这里面了
sharedInstance = this.getSingleton(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
try {
//这里是获取一个FactoryBean对象--创建对象的主要逻辑了
return AbstractBeanFactory.this.createBean(beanName, mbd, args);
} catch (BeansException var2) {
AbstractBeanFactory.this.destroySingleton(beanName);
throw var2;
}
}
});
(4):AbstractBeanFactory.createBean(beanName,mbd,args)【不重要的代码块已删除】
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
Object beanInstance;
try {
//这里本来想删除来,但是这里是实现代理的重要地方,利用后置处理器完成,暂时保留,但是不讲解,在获取bean的时候【没有代理的时候】没有用,可以忽略,等将后置处理器的时候再进行讲解
beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
if (beanInstance != null) {
return beanInstance;
}
} catch (Throwable var8) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var8);
}
//又是相似的命名逻辑,createBean-->doCreateBean,真正操作的逻辑都是在do开头的方法里面
beanInstance = this.doCreateBean(beanName, mbdToUse, args);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
createBean里面又调用了doCreateBean,真正的逻辑再doCreateBean里面,方法命名形式眼熟不,(getSingleton-->doGetSingleton)
因此,我们到doCreateBean里面看下真正的操作(这个方法很复杂+重要,spring的后置处理器在这里体现的淋漓尽致)
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
//BeanWrapper 可以理解为bean的包装类,BeanWrapper我们可以获取到bean
if (instanceWrapper == null) {
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null;
Class<?> beanType = instanceWrapper != null ? instanceWrapper.getWrappedClass() : null;
mbd.resolvedTargetType = beanType;
synchronized(mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//bean的后置处理器--暂时可以忽略
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable var17) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
}
mbd.postProcessed = true;
}
}
//判断我们这个bean是否可以被提前创建-说白了就是可以不可以被循环依赖
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if (earlySingletonExposure) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
}
//如果可以循环依赖的话就把bean加入到singletonfactory中,之后单独拿出来写一下如何解决的循环依赖
this.addSingletonFactory(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
return AbstractAutowireCapableBeanFactory.this.getEarlyBeanReference(beanName, mbd, bean);
}
});
}
Object exposedObject = bean;
try {
//属性注入,也是利用后置处理器完成的【又是一块很复杂且重要的代码】
this.populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
}
} catch (Throwable var18) {
if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
throw (BeanCreationException)var18;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
}
//这里有代码,不重要,已删除
try {
this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
} catch (BeanDefinitionValidationException var16) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
}
}
4:结语
以上,就是spring getBean的源码概览,挖了很多坑,例如,spring是如何解决循环依赖的;spring后置处理器如何操作,在getBean的过程中如何在哪里有应用后置处理器;spring如何进行属性注入【其实也是利用后置处理器】;再进一步,spring aop是怎么实现的【也是在getBean这个实现的】。接下来的一段时间,会慢慢把这些坑给填上的~