Spring源码学习总结(三):从bean实例获取对象(getObjectForBeanInstance)

本文是关于Spring源码分析的总结,重点探讨了getObjectForBeanInstance方法的作用和流程。首先介绍了方法的整体调用路径,接着详细剖析了AbstractBeanFactory中的关键步骤,包括mergedLocalBeanDefinition的合并与转换,以及getObjectFromFactoryBean的核心实现,特别是FactoryBean的处理。通过这些步骤,展示了如何从bean实例获取最终的对象。
摘要由CSDN通过智能技术生成

这篇文章主要是学习《Spring源码深度解析》后对getObjectForBeanInstance方法的学习总结

1.代码整体方法调用

  • 2. AbstractBeanFactory#getObjectForBeanInstance
    • 2.1 AbstractBeanFactory#getMergedLocalBeanDefinition
    • 2.2 AbstractBeanFactory#getObjectFromFactoryBean
      • 2.2.1 doGetObjectFromFactoryBean
        • 2.2.1.1 FactoryBean.getObject
      • 2.2.2 postProcessObjectFromFactoryBean

  接下来逐个看代码分析

2.AbstractBeanFactory#getObjectForBeanInstance

  方法 AbstractBeanFactory#getObjectForBeanInstance 在 getBean 方法中是个高频用法,在getBean中不论是用什么方式获得的bean,都会执行getObjectForBeanInstance方法。原因是,不论哪种方式获得的bean都是原始的bean状态,并不是我们真正想要的。
这段代码主要功能
1.辅助性检查;
2.进行了子类父类的合并,并把存储xml配置的GernericBeanDefinition转换为RootBeanDefinition;
3.真正核心是调用了getObjectFromFactoryBean这个方法。
  代码如下:

//name:getBean方法传入的name,beanName:处理过后的name,mbd:null
protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
   

		//整个这个判断的意思是说,如果要获取的bean是FactoryBean的引用,但是beanInstance不是FactoryBean的就抛异常
		//判断输入的bean的name是否是工厂相关的(前缀是&) 
		if (BeanFactoryUtils.isFactoryDereference(name)) {
   
			if (beanInstance instanceof NullBean) {
   
				return beanInstance;
			}
			//name的前缀是&,但是类型不是FactoryBean,就报错
			if (!(beanInstance instanceof FactoryBean)) {
   
				throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
			}
		}

		// 现在可以确定的是,这个bean实例,要么是个正常bean,要么是个FactoryBean
		// 这两个判断条件
		//第一个是说如果这个bean实例不是FactoryBean,就直接返回beanInstance,因为不是FactoryBean那肯定就是正常的bean了
		//第二个是说,如果本来期望返回的就是FactoryBean,那么也可以就直接返回了
		if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
   
			return beanInstance;
		}

		Object object = null;
		if (mbd == null) {
   
			//尝试从缓存获取bean
			object = getCachedObjectForFactoryBean(beanName);
		}
		if (object == null) {
   
			//强转为beanFactory。此时的beanInstance一定是FactoryBean类型的,因为如果不是,就会在上面的if中直接返回了
			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
			//检测这个bean是否已经被加载过
			//containsBeanDefinition中会返回beanDefinitionMap.containsKey(beanName)的值
			if (mbd == null && containsBeanDefinition(beanName)) {
   
				//进行父类和子类的合并,把存储xml配置的GernericBeanDefinition转换为RootBeanDefinition
				mbd = getMergedLocalBeanDefinition(beanName);
			}
			//判断mdb是否为空,以及检测是不是系统创建的
			boolean synthetic = (mbd != null && mbd.isSynthetic());
			//把核心功能托付给getObjectFromFactoryBean
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		return object;
	}

再说一下,这段代码干了什么
1.辅助性检查;
2.进行了子类

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值