if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
那什么时候执行这个工厂方法呢?当你依赖到了该Bean而单例缓存里面有没有该Bean的时候就会调用该工厂方法生产Bean,看下getSingleton的实现:
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory singletonFactory = (ObjectFactory) this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
现在有两个疑问了,就举个对Bean进行Wrap的操作吧,Spring是如何规避重复Wrap的呢?
1)从代码可以看到,执行完工厂方法会缓存到earlySingletonObjects中,因此再次调用该方法不会重复执行Wrap的
2)对于有些BeanPostProcessor提供对Bean的Wrap的操作,但是生命周期位于在set操作之后,如果提前暴露出去被其他Bean执行了工厂方法给Wrap起来,回过来自己再执行BeanPostProcessor的后处理操作的时候不会发生重复吗?
【AbstractAutoProxyCreator】
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
this.earlyProxyReferences.add(cacheKey);
return wrapIfNecessary(bean, beanName, cacheKey);
}
【AbstractAutoProxyCreator】
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
return bean;
}
这个BeanPostProcessor很典型了,用于创建代理类的 。一般这种BeanPostProcessor总要提供一个getEarlyBeanReference的接口供其他Bean使用,而又防止了其他类直接使用到该类最原始的版本 。这就是上述两个方法如此相似的原因 。置于略微的差异,你应该看出来,是防止重复执行方法 。
4、初始化Bean,执行一个个BeanPostProcessor
protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(this);
}
Object wrAppedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
你不能保证这些乱七八糟的BeanPostProcessor会不会改变Bean的版本,当然,如果改变了,肯定要出错的,在这里,Spring就没有做依赖解决了(都给你把代理类解决了你还想啥呢),只是做了检查,如下 。
5、循环依赖解决不了的情况下的依赖检查
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set actualDependentBeans = new LinkedHashSet(dependentBeans.length);
for (int i = 0; i < dependentBeans.length; i++) {
String dependentBean = dependentBeans[i];
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
推荐阅读
- 柚子头尖的好还是圆的好 柚子平头和尖头哪个好吃
- 如何对网站进行有效的SEO操作?
- JS中操作DOM是"同步"还是"异步"
- 梦到门牙掉了还出血了预示着什么? 梦到门牙掉了是什么意思 周公解梦
- 如何增加小程序曝光?
- 梦见猪屎弄到自己身上是什么意思 梦见猪屎满地都是什么意思
- 快手主页上的快手小店是怎么设置的 快手小店怎么上传单号
- 什么是数据库分库分表?
- 冲泡黄山毛峰有以下几点是要值得注意
- 肉松椒盐发面饼的做法
