引言
我们在上一篇文章中着重分析了FactoryBean中getObjectType方法的流程,最后还画了一个大概的流程图,描述了我们传入的class类型(IOrderService.calss)与我们自定义的FactoryBean子类之间如何关联起来的,即我们调用getBean(IOrderService.class),底层最终会调用factoryBean.getObjectType()。
这一篇文章我们将分析FactoryBean是如何让Spring容器管理调用它的getObject()所生成的Bean,接着上篇的后续分析(如下图):
DefaultListableBeanFactory # resolveNamedBean
此时部分变量值如下:
- requiredType:IOrderService.class
- candidateNames:{“orderFactoryBean”}
因为candidateNames数组长度为1,会进入到getBean(beanName, requiredType, args)方法,这个方法又调用了doGetBean方法,doGetBean是Spring容器初始化时很重要的部分,但这里不会去分析太多Spring Bean生命周期的内容,我们在这篇文章中只关注和FactoryBean相关的内容。
AbstractBeanFactory # doGetBean (省略部分无关代码)
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//转换传入的BeanName的值,如&name变为name 以及别名(alias)的转换
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
//调用getSingleton方法 从Spring容器中获取单例Bean,下面再具体分析此方法
//这里的beanName为orderFactoryBean,获取到的是它对应的OrderFactoryBean实例(因为我们有添加@Component注解,spring容器中已创建该bean)
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
//这里是根据获取到的OrderFactoryBean实例本身去获取对象
//注意这里传入了name和转换后的beanName
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
DefaultSingletonBeanRegistry # getSingleton,从Spring容器中获取单例Bean
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//先从singletonObjects单例池(一级缓存)中获取Bean,singletonObjects是一个ConcurrentHashMap
//key是beanName value是单例Bean
Object singletonObject = this.singletonObjects.get(beanName);
//如果单例池中不存在,并且是当前正在创建中的Bean
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 加锁
synchronized (this.singletonObjects) {
//从二级缓存中获取早期的bean
singletonObject = this.earlySingletonObjects.get(beanName);
//如果没有获取到,并且允许提前引用相应的Bean(依赖注入)
if (singletonObject == null && allowEarlyReference) {
//singletonFactories俗称三级缓存,key:beanName,value:ObjectFactory
// 这个ObjectFactory是一个函数式接口,所以支持Lambda表达式:() -> getEarlyBeanReference(beanName, mbd, bean)
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//从ObjectFactory中获取Bean实例
singletonObject = singletonFactory.getObject();
//放入earlySingletonObjects这个Map二级缓存中,依赖注入时用到
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
该方法很重要,涉及到了Spring容器中的三级缓存:
- 一级缓存:singletonObjects,缓存的是已经经历了完整生命周期的bean对象。
- 二级缓存:earlySingletonObjects,比singletonObjects多了一个early,表示缓存的是早期的bean对象(或者:缓存提前拿原始对象进行了AOP之后得到的代理对象)。早期是什么意思?表示Bean的生命周期还没走完就把这个Bean放入了earlySingletonObjects。
- 三级缓存:singletonFactories,缓存的是ObjectFactory,表示对象工厂,用来创建某个对象的。
其中二级缓存主要是为了解决Spring中的循环依赖,singletonFactories主要用来去生成原始对象进行了AOP之后得到的代理对象,具体可参考《【面试题】终于有人能把Spring的循环依赖讲清楚了》,写得很棒。
下面回归正题,接着分析 AbstractBeanFactory # getObjectForBeanInstance
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// 如果传进来的OrderFactoryBean不属于FactoryBean的实例,则直接返回当前实例(表示它是普通的bean)
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
// 如果是FactoryBean子类bean
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
}
else {// 缓存中获取
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
//如果能走到这里来,说明这个bean实例是FactoryBean类型的
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 从该方法名字看出:从FactoryBean中获取对象,下面再具体分析
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
分析 FactoryBeanRegistrySupport # getObjectFromFactoryBean
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
//FactoryBean类型的实例是否单例
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
//从缓存中获取
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
//缓存获取不到,则调用doGetObjectFromFactoryBean方法从FactoryBean中获取bean对象
//这里是调用的FactoryBean的getObject方法来获取的,具体看这一步
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
//再从缓存中获取一次
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
//如果上一步的缓存中获取到了,则用缓存中的替代FactoryBean中获取的bean
if (alreadyThere != null) {
object = alreadyThere;
}
else {
if (shouldPostProcess) {
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
beforeSingletonCreation(beanName);
try {
//调用BeanPostProcessor中的postProcessAfterInitialization方法进行处理
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
afterSingletonCreation(beanName);
}
}
if (containsSingleton(beanName)) {
//添加到factoryBeanObjectCache中缓存,key为beanName
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
else {
//FactoryBean的实例非单例情况
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
分析doGetObjectFromFactoryBean,这里是调用的FactoryBean的getObject方法来获取对象
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
// 终于看到了FactoryBean中的getObject(),真相大白
object = factory.getObject();
}
}
return object;
}
大致流程图(引用)
总结
大概的流程:根据我们传入的Class类型,循环Spring容器中所有的BeanNames,再根据beanName获取对应的Bean实例,判断获取的Bean实例是不是FactoryBean类型的Bean;如果是,则调用FactoyBean的getObjectType方法获取Class,将获取到的Class和传入的Class进行匹配;如果匹配到,则将此beanName和传入的Class建立一个映射关系。再根据beanName获取到Spring容器中对应的FactoryBean的实例bean,调用该FactoryBean的getObject方法来获取我们方法中自定义的bean。
参考:https://conan.blog.csdn.net/article/details/79588391
●阿里巴巴为什么能抗住90秒100亿?--服务端高并发分布式架构演进之路
●SpringCloud电商秒杀微服务-Redisson分布式锁方案
查看更多好文,进入公众号--撩我--往期精彩
一只 有深度 有灵魂 的公众号0.0