spring源码的重要扩展接口BeanFactoryPostProcessor、BeanPostProcessor、aware, 循环依赖, @Async会引起循环依赖问题

BeanFactoryPostProcessor

加强出来beanDefinition信息的比如处理${},对配置文件进行解密操作
spring会扫描只B要是实现了beanFactoryPostProcessor接口且注册到容器中的bean都会执行beanFactoryPostProcessor接口中的postProcessBeanDefinitionRegistry方法,如
( PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());源码中的一小段)

  invokeBeanFactoryPostProcessors((Collection)orderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList();
        Iterator var24 = currentRegistryProcessors.iterator();

        while(var24.hasNext()) {
            ppName = (String)var24.next();
            //扫描实现BeanFactoryPostProcessor接口的类--
            nonOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
        }

        invokeBeanFactoryPostProcessors((Collection)nonOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
// 执行invokeBeanFactoryPostProcessors
private static void invokeBeanFactoryPostProcessors(Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
        Iterator var2 = postProcessors.iterator();

        while(var2.hasNext()) {
            BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var2.next();
            // 执行postProcessBeanFactory
            postProcessor.postProcessBeanFactory(beanFactory);
        }

    }

例子:

PropertySourcesPlaceholderConfigurer解析替换${}
EncryptablePropertySourceBeanFactoryPostProcessor对配置文件中密码进行密文解密

InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor接口继承beanFactoryPostProcessor
一般作用:给bean一个不需要走bean生命周期实例化流程 的创建bean方式
spring在createBean时有这么一个判断

    Object beanInstance;
        try {
            beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
            if (beanInstance != null) {
                return beanInstance;
            }
        } catch (Throwable var10) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var10);
        }

this.resolveBeforeInstantiation(beanName, mbdToUse);会调用到applyBeanPostProcessorsBeforeInstantiation方法

    @Nullable
    protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
        Iterator var3 = this.getBeanPostProcessors().iterator();

        while(var3.hasNext()) {
            BeanPostProcessor bp = (BeanPostProcessor)var3.next();
            //可以看到只要实现了applyBeanPostProcessorsBeforeInstantiation接口就执行然后获取到对象直接返回,生命周期无需继续进行
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
                Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
                if (result != null) {
                    return result;
                }
            }
        }

        return null;
    }

BeanPostProcessor

bean的后置处理器,AOP的实现
AbstractApplicationContext中的 registerBeanPostProcessors方法会扫描bean中实现了BeanPostProcessor接口的类。

在bean初始化时会调用该接口的方法(AbstractAutowireCapableBeanFactory的 initializeBean方法)

 Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
         //BeanPostProcessor前置方法
            wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
        }

        try {
            this.invokeInitMethods(beanName, wrappedBean, mbd);
        } catch (Throwable var6) {
            throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
        }

        if (mbd == null || !mbd.isSynthetic()) {
        //BeanPostProcessor后置方法
            wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

aware

和BeanPostProcessor类似
初始化bean会执行以下方法,如果bean实现了Aware接口就会执行相应的方法。如下代码所示。

 private void invokeAwareMethods(String beanName, Object bean) {
        if (bean instanceof Aware) {
            if (bean instanceof BeanNameAware) {
                ((BeanNameAware)bean).setBeanName(beanName);
            }

            if (bean instanceof BeanClassLoaderAware) {
                ClassLoader bcl = this.getBeanClassLoader();
                if (bcl != null) {
                    ((BeanClassLoaderAware)bean).setBeanClassLoader(bcl);
                }
            }

            if (bean instanceof BeanFactoryAware) {
                ((BeanFactoryAware)bean).setBeanFactory(this);
            }
        }

    }

初始化populateBean方法

填充属性bean的注入

beanFactory和FactoryBean的区别

beanFactory是完成遵行springBean的生命周期的
FactoryBean是不需要遵行生命周期

循环依赖(一二三级缓存)

spring只是解决了单利对象的循环依赖
一级是完整对象(spring中单利bean的实现)
二级是半成品(提前暴露对象引用)
三级是lamda表达式
三级缓存是为AOP考虑的,因为AOP会产生代理对象所以提前暴露的话就要暴露代理对象才对。这里存的是一个函数如果需要提前暴露的话就提前进行AOP,没有调用到提前暴露就等到初始化后在进行AOP操作。

@Async会引起循环依赖问题

三级缓存中有判断【bp instanceof SmartInstantiationAwareBeanPostProcessor】而AsyncAnnotationBeanPostProcessor没有实现SmartInstantiationAwareBeanPostProcessor
相当于三级缓存失效。所以会导致提前暴露的对象不是代理对象从而引发循环依赖问题。

 protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
        Object exposedObject = bean;
        if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
            Iterator var5 = this.getBeanPostProcessors().iterator();

            while(var5.hasNext()) {
                BeanPostProcessor bp = (BeanPostProcessor)var5.next();
                if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                    SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor)bp;
                    exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
                }
            }
        }

        return exposedObject;
    }

//对bean进行增强操作后会二次检测。AbstractAutowireCapableBeanFactory的
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException 方法。下面是关键的一部分。

    Object exposedObject = bean;

        try {
            this.populateBean(beanName, mbd, instanceWrapper);
            //AOP的bean会生成一个代理对象导致exposedObject != bean.
            //如果三级缓存存在循环依赖的会提前进行AOP,这里返回的就还是原来的bean
            exposedObject = this.initializeBean(beanName, exposedObject, mbd);
        } catch (Throwable var18) {
            if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
                throw (BeanCreationException)var18;
            }

            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
        }
        
  if (earlySingletonExposure) {
            Object earlySingletonReference = this.getSingleton(beanName, false);
            if (earlySingletonReference != null) {
                //@Async生成了代理对象后exposedObject == bean就不成立了。一个是提前暴露的对象,一个是代理对象。
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;
                } else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
                    String[] dependentBeans = this.getDependentBeans(beanName);
                    Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
                    String[] var12 = dependentBeans;
                    int var13 = dependentBeans.length;

                    for(int var14 = 0; var14 < var13; ++var14) {
                        String dependentBean = var12[var14];
                        if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            actualDependentBeans.add(dependentBean);
                        }
                    }

//触发循环依赖exception
                    if (!actualDependentBeans.isEmpty()) {
                        throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
                    }
                }
            }
        }

@Async生成了代理对象后exposedObject == bean就不成立了。一个是提前暴露的对象,一个是代理对象。普通的对象因为实现SmartInstantiationAwareBeanPostProcessor接口存在循环依赖的话就会提前进行AOP不会对bean再次增强所【exposedObject = = bean会成立】

spring事务的传播性

待补充

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值