bean的实例中获取对象

在bean的加载流程中有一个非常高频的方法:getObjectForBeanInstance().这个方法是我们在得到bean的实例之后要做的,这个方法主要功能就是检测一下bean是不是FactoryBean类型的,如果是则需要调用getObject方法,具体的FactoryBean的使用,在之前的文章里有分析过.
上源码分析一下

protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

		// 判断name是不是以 & 开头的
		if (BeanFactoryUtils.isFactoryDereference(name)) {
			if (beanInstance instanceof NullBean) {
				return beanInstance;
			}
			// 说明以&开头,但不是FactoryBean类型,则直接抛出异常
			if (!(beanInstance instanceof FactoryBean)) {
				throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
			}
			if (mbd != null) {
				mbd.isFactoryBean = true;
			}
			// 因为name是以&开头的,说明获取的就是FactoryBean本身,所以不用调用getObject方法
			return beanInstance;
		}

		// 到这里说明name并不是以&开头的,这时候就需要判断bean是不是FactoryBean类型的了
		if (!(beanInstance instanceof FactoryBean)) {
			// 如果不是则直接返回
			return beanInstance;
		}
		// 到这里说明name不是以&开头,并且bean是FactoryBean类型的了
		// 根据FactoryBean的用法,我们知道需要调用getObject方法得到真正的bean
		Object object = null;
		if (mbd != null) {
			mbd.isFactoryBean = true;
		}
		else {
			// 尝试从缓存中加载
			object = getCachedObjectForFactoryBean(beanName);
		}
		if (object == null) {
			// 缓存中没有,把bean强转为FactoryBean
			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
			// containsBeanDefinition检测beanDefinitionMap中
			// 也就是所有已经加载的类中检测是否定义beanName
			if (mbd == null && containsBeanDefinition(beanName)) {
				// 如果有则把GenericBeanDefinition转为RootBeanDefinition,
				// 如果指定的beanName是子bean的化,同时会合并父类的相关属性
				mbd = getMergedLocalBeanDefinition(beanName);
			}
			// 是否用户定义的而不是应用程序本身定义的
			boolean synthetic = (mbd != null && mbd.isSynthetic());
			// 核心方法
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		return object;
	}

上面提到很多factoryBean的使用,如果不知道的,可以查看我的另一篇文章,讲FactoryBean的使用的,看完,在看上面的分析,可能会好一些.FactoryBean的用法

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
		// 判断是否是单例
		if (factory.isSingleton() && containsSingleton(beanName)) {
			synchronized (getSingletonMutex()) {
				// 如果是单例尝试从缓存中中获取
				Object object = this.factoryBeanObjectCache.get(beanName);
				if (object == null) {
					// 缓存中无,这个方法的核心是调用了factoryBean的getObject
					object = doGetObjectFromFactoryBean(factory, beanName);
					// 得到之后,再尝试从缓存中获取
					Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
					if (alreadyThere != null) {
						// 如果此时缓存中有了,就直接取缓存中的值,避免循环依赖重复创建
						object = alreadyThere;
					}
					else {
						// 如果缓存中没有,则先判断需不需要执行后处理器
						if (shouldPostProcess) {
							// 如果当前bean正在创建中,则不需要执行,
							// 因为产生了循环依赖,所以才会进入这里,当前bean还没有创建完成
							// 等到bean创建完成之后,还会再进行处理的.
							if (isSingletonCurrentlyInCreation(beanName)) {
								// Temporarily return non-post-processed object, not storing it yet..
								return object;
							}
							// 把beanName加入到singletonsCurrentlyInCreation中
							// 记录加载状态.上面那个判断也是根绝这个集合来判断的
							beforeSingletonCreation(beanName);
							try {
								// 执行后处理器
								object = postProcessObjectFromFactoryBean(object, beanName);
							}
							catch (Throwable ex) {
								throw new BeanCreationException(beanName,
										"Post-processing of FactoryBean's singleton object failed", ex);
							}
							finally {
								// 把beanName从singletonsCurrentlyInCreation中移除
								// 即结束bean的加载状态
								afterSingletonCreation(beanName);
							}
						}
						if (containsSingleton(beanName)) {
							// 添加缓存,如果是循环依赖的话,这里依旧没有加入缓存
							this.factoryBeanObjectCache.put(beanName, object);
						}
					}
				}
				return object;
			}
		}
		else {
			// 如果不是单例,直接调用factoryBean的getObject方法即可
			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;
		}
	}

这里分析一下bean后处理器做了什么事情:

protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
        return this.applyBeanPostProcessorsAfterInitialization(object, beanName);
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
        Object result = existingBean;

        Object current;
        // 获取所有的beanPostProcessors,并且遍历
        for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) {
            BeanPostProcessor processor = (BeanPostProcessor)var4.next();
            // 调用后处理器的初始化方法.
            // 其实beanProcessor是Spring的扩展功能,我们可以通过实现BeanProcessor进行扩展
            current = processor.postProcessAfterInitialization(result, beanName);
            if (current == null) {
                return result;
            }
        }

        return result;
    }

对于后处理器除了BeanPostProcessor之外还有BeanFactoryPostProcessor,这些都是Spring留给我们的口子,通过实现这些接口,来进行扩展,以后慢慢会提到.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值