SmartInstantiationAwareBeanPostProcessor

BeanPostProcessor是spring的bean后置处理器,这个接口定义了两个方法分别在bean的初始化前、初始化后执行。

InstantiationAwareBeanPostProcessor继承自BeanPostProcessor,添加了两个方法,这两个方法分别在bean的实例化前、实例化后执行。

SmartInstantiationAwareBeanPostProcessor又继承自InstantiationAwareBeanPostProcessor,添加了几个方法,其中有个方法是:

default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
		return bean;
	}

在AbstractAutowireCapableBeanFactory的doCreateBean()方法中,在对bean实例化以后填充属性之前(一般称为早起对象),会将其放入第三级缓存

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {

		
		BeanWrapper instanceWrapper = null;
		//省略其他代码……
		//从beanWrapper中获取我们的早期对象(实例化后的对象)
		final Object bean = instanceWrapper.getWrappedInstance();
		
        //省略其他代码……
		

		
		//缓存单例到三级缓存中,以防循环依赖		
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		//上述条件满足,允许中期暴露对象
		if (earlySingletonExposure) {
			
			//把我们的早期对象包装成一个singletonFactory对象 该对象提供了一个getObject方法,该方法内部调用getEarlyBeanReference方法
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		//省略其他代码……
	}

由上边代码可见,早起对象放入缓存时,是包装成ObjectFactory然后放入其中:

addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

 addSingletonFactory()方法:

protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(singletonFactory, "Singleton factory must not be null");
		//同步加锁
		synchronized (this.singletonObjects) {
			//单例缓存池中没有包含当前的bean
			if (!this.singletonObjects.containsKey(beanName)) {
				//加入到三级缓存中,,,,,暴露早期对象用于解决循环依赖
				this.singletonFactories.put(beanName, singletonFactory);
				this.earlySingletonObjects.remove(beanName);
				this.registeredSingletons.add(beanName);
			}
		}
	}

 getEarlyBeanReference()方法:

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
		Object exposedObject = bean;
		//判读我们容器中是否有InstantiationAwareBeanPostProcessors类型的后置处理器
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			//获取我们所有的后置处理器
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				//判断我们的后置处理器是不是实现了SmartInstantiationAwareBeanPostProcessor接口
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					//进行强制转换
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					//挨个调用SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference
					exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
				}
			}
		}
		return exposedObject;
	}

可见该方法被调用时,会调用SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference()方法。

 AbstractAutoProxyCreator是SmartInstantiationAwareBeanPostProcessor的实现类之一,其重写了getEarlyBeanReference方法:

@Override
	public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		this.earlyProxyReferences.put(cacheKey, bean);
		return wrapIfNecessary(bean, beanName, cacheKey);
	}
wrapIfNecessary()方法:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		//已经被处理过(解析切面时targetSourcedBeans出现过) 就是自己实现创建动态代理逻辑
		if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
			return bean;
		}
		//不需要增强的
		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
			return bean;
		}
		//是不是基础的bean 是不是需要跳过的 重复判断 ( 因为循环依赖是可以改变bean的,如果把bean改成了advisor呢)
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}

		// 根据当前bean找到匹配的advisor
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		// 当前bean匹配到了advisor
		if (specificInterceptors != DO_NOT_PROXY) {
			// 标记为已处理
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			//创建我们的真正的代理对象
			Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
			//加入到缓存
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}

		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

可见,其和动态代理有关。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值