spring源码-refresh中的bean初始化getBean方法(上)
在前面没有讲过getBean方法,在这里将getBean方法讲述一下
getBean方法很多地方都有,但是他们都是通过DefaultListableBeanFactory通过多态的形式进行的调用,所以它的getBean唯一方法只可能出现在它的父类也就是AbstractBeanFactory中
然后又调用了本类的doGetBean方法,这个方法比较长,我们主要分成三个部分来进行查看,首先是第一部分
这里的transformdBeanName是在干什么?我们先要知道一点

知道这一点,我们再来看transformdBeanName方法
先看参数

那这个参数就是在查找是否是beanFactory,如果没有&符号则返回,如果有那么就去做do while循环一直移除&符号,直到没有&符号开头再返回

再看外面这个方法

做如果是别名的话获取真实名称,那么这一块的话就是transformedBeanName的方法,是想要获取到真实可靠能够被初始化的一个beanName

然后的话看到getSingleton方法,这一块就是判断是否有在三级缓存中有缓存了的Bean可以拿,如果有则不用再重复创建了,可以直接拿到对象实例。如果自己手写过spring三级缓存的就不会陌生

首先就是从单例池中获取看看有没有,如果没有的话呢就说明至少到目前为止,还没有创建出来这个beanName完整的bean,那么如果一级缓存中没有,且
如果beanName存在于这个正在创建中的set,那么就说明这个这个bean是再二级缓存或者三级缓存中,然后我们去二级缓存中拿,如果拿到还是二级缓存中还是没有,并且给定了allowEarlyReference允许,那么找到的就是三级缓存,然后到三级缓存中,我们能够通过三级缓存拿到代理对象,并存放进二级缓存中,并清除三级缓存的代理对象
继续回到这一块

总之如果在缓存中能够拿到,那么就进入去getObjectForBeanInstance

进入isFactoryDereference其实还是一样的,判断从getBean->doGetBean传进来想要拿到的name是不是FactoryBean,这里的name和beanName要做一个区别

我们能够看到,name是由最外层方法传进来的,beanName是根据name进行获取的,所以这里还是再做name是否是FactoryBean的校验,如果是的话就去instance nullbean,就是看看是不是为空,空则直接返回,
既然通过了isFactoryDereference的校验,那么就肯定是&开头,那么必须是FactoryBean,那么判断如果不是则报错,最后我们的mbd传进来的null空的
那么这里的判断就进不去,最后返回实例
再看下一段

再去判断拿到的实例如果不是FactoryBean,那么就直接返回,如果是的话,就继续往下,将object置为空,mbd传进来为空,则不进入判断,直接进入else,getCachedObjectForFactoryBean
这里的factoryBeanObjectCache只是用来辅助三级缓存的一个缓存,有问题直接问ai
,就不过多赘述
然后进入object==null,这里已经能确定实例是FactoryBean了,那么做一个强转,如果mbd为空且beanName在一级缓存单例池中存在换句话说就是完成了初始化。那么就去做mbd的整合自己和父类的所有BeanDefinition,然后判断synthetic是否是符合的,最后再去getObjectFromFactoryBean
这个方法

首先判断是singleton的,肯定是再去判断一级缓存单例池中是否存在beanName,如果是单例并且已经初始化完成了,那么就进入判断,拿到辅助缓存的对象,如果缓存中没有,那么就去doGetObjectFromFactoryBean
可以看到,有两个getObject方法,这个getObject就看传入的factory是顶级接口FactoryBean的哪个子类了,如果是有AOP的就会去拿到代理对象,如果是普通对象,就会拿到普通对象
再回来看

当对象在 doGetObjectFromFactoryBean 执行期间被其他依赖提前缓存时,直接复用,避免重复后置处理,如果不为空那就不做后置处理了,如果为空就进入else,shouldPostProcess主要看是否合成
,如果是合成的那么就不会后置处理,放入缓存中直接返回,如果是合成的那么还会判断是不是还在创建中,如果是那么就直接返回,这个属于延迟加载的判断,然后再做beforeSingleton的校验
singletonsCurrentlyInCreation是set如果加入不了则抛出异常说明已经存在创建中,然后开始做postProcessObjectFromFactoryBean这里面开始做后置处理,最后调用afterSingletonCreation
将刚才加入的beanName移除掉。
以上是if (factory.isSingleton() && containsSingleton(beanName))为true的情况下,也就是说为单例的情况下
如果为false则走else

就是prototype的情况,那么每次直接去get一个object就不用考虑缓存中只有一个的问题了,然后去执行后置处理
到此为止getObjectForBeanInstance的方法就结束了

同时我们讲解的getBean第一部分也完成了


浙公网安备 33010602011771号