【Spring源码:FactoryBean二】终于弄懂FactoryBean是如何自定义bean的创建过程了

引言

我们在上一篇文章中着重分析了FactoryBeangetObjectType方法的流程,最后还画了一个大概的流程图,描述了我们传入的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的循环依赖讲清楚了》,写得很棒。

下面回归正题,接着分析 AbstractBeanFactorygetObjectForBeanInstance

	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

史上最强Tomcat8性能优化

阿里巴巴为什么能抗住90秒100亿?--服务端高并发分布式架构演进之路

B2B电商平台--ChinaPay银联电子支付功能

学会Zookeeper分布式锁,让面试官对你刮目相看

SpringCloud电商秒杀微服务-Redisson分布式锁方案

查看更多好文,进入公众号--撩我--往期精彩

一只 有深度 有灵魂 的公众号0.0

猜你喜欢

转载自blog.csdn.net/a1036645146/article/details/111736852
今日推荐