Spring三级缓存、循环依赖、AOP

Spring三级缓存、循环依赖、AOP

1. 简介

三级缓存:

缓存属性说明
一级缓存singletonObjects保存初始化的单例Bean
二级缓存earlySingletonObjects保存实例化、未初始化的单例Bean
三级缓存singletonFactories保存实例化的单例Bean

循环依赖:两个Bean互相依赖的场景

2. 流程

入口

@EnableAspectJAutoProxy,作用:@Import(AspectJAutoProxyRegistrar.class)

@Import(AspectJAutoProxyRegistrar.class),作用:向IoC容器注册自动代理创建器BeanDefinition

自动代理创建器

优先级从低到高:

  1. InfrastructureAdvisorAutoProxyCreator

  2. AspectJAwareAdvisorAutoProxyCreator

  3. AnnotationAwareAspectJAutoProxyCreator

作用:属于Bean后置处理器,或是早期暴露、或是后置处理时创建代理

创建代理流程

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    if (bean != null) {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (this.earlyProxyReferences.remove(cacheKey) != bean) {
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}
  1. 获取所有增强器

  2. 找出canApply的增强器

  3. 排序

  4. 创建代理

    @Override
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
            Class<?> targetClass = config.getTargetClass();
            if (targetClass == null) {
                throw new AopConfigException("TargetSource cannot determine target class: " +
                                             "Either an interface or a target is required for proxy creation.");
            }
            if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
                return new JdkDynamicAopProxy(config);
            }
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            return new JdkDynamicAopProxy(config);
        }
    }
    

3. 三级缓存与早期暴露

场景:现有两个Bean(A、B),先进行A的创建,后进行B的创建

AB都不是代理

  1. A:实例化、属性填充

  2. B:实例化、属性填充

    1. 触发getEarlyBeanReference获取A的早期引用
    2. A进入二级缓存
    3. B继续剩余属性填充、初始化
    4. B进入一级缓存
  3. A继续剩余属性填充、初始化

  4. A进入一级缓存

B是代理

  1. A:实例化、属性填充

  2. B:实例化、属性填充

    1. 触发getEarlyBeanReference获取A的早期引用
    2. A进入二级缓存
    3. B继续剩余属性填充、初始化创建代理(后置处理时生成)
    4. B进入一级缓存
  3. A继续剩余属性填充、初始化

  4. A进入一级缓存

A是代理

  1. A:实例化、属性填充

  2. B:实例化、属性填充

    1. 触发getEarlyBeanReference获取A的早期引用,生成代理(早期暴露时生成)
    2. A代理进入二级缓存
    3. B继续剩余属性填充、初始化
    4. B进入一级缓存
  3. A继续剩余属性填充、初始化

  4. A早期暴露回调:使用二级缓存的代理,替换被代理对象A

  5. A进入一级缓存

AB都是代理

  1. A:实例化、属性填充

  2. B:实例化、属性填充

    1. 触发getEarlyBeanReference获取A的早期引用,生成代理(早期暴露时生成)
    2. A进入二级缓存
    3. B继续剩余属性填充、初始化,生成代理(后置处理时生成)
    4. B进入一级缓存
  3. A继续剩余属性填充、初始化(后置处理,创建代理前提条件不满足,直接返回。原因:earlyProxyReferences存在)

  4. A早期暴露回调:使用二级缓存的代理,替换被代理对象A

  5. A进入一级缓存

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值