IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 多图剖析|Spring的循环依赖竟如此复杂 -> 正文阅读

[Java知识库]多图剖析|Spring的循环依赖竟如此复杂

Spring的循环依赖

spring4和5的AOP区别

spring4的执行顺序:

对应springboot1.x

@Before(前置通知)=》@After(后置通知)=》@AfterReturning(正常返回)

@Before(前置通知)=》@After(后置通知)=》@AfterThrowing(方法异常)

spring5的执行顺序:

对应springboot2.x

@Before(前置通知)=》@AfterReturning(正常返回)=》@After(后置通知)

@Before(前置通知)=》@AfterThrowing(方法异常)=》@After(后置通知)

什么是循环依赖

多个Bean之间相互依赖,形成一个闭环。

在这里插入图片描述

使用构造函数注入bean时若存在循环引用将会报错,若使用set()注入bean时存在循环引用不会报错;

Spring容器

默认的单例(Singleton)的场景是支持循环依赖的不会报错,但原型(Prototype)的场景是不支持循环依赖的,会报错;

  • 当两个互相引用的bean都是单例的或者其中一个是单例的则可正常创建两个bean对象;其是通过三级缓存模型解决的;

    // 控制台专门输出A,B创建成功
    @Component
    public class CircleRefA {
        @Autowired
        private CircleRefB circleRefB;
    
        @PostConstruct
        public void init() {
            System.out.println("CircleRefA 创建成功");
        }
    }
    @Component
    public class CircleRefB {
        @Autowired
        private CircleRefA circleRefA;
    
        @PostConstruct
        public void init() {
            System.out.println("CircleRefB 创建成功");
        }
    }
    
  • 若两个都为原型模式,则报错

    // 若是原型模式
    @Component
    @Scope("prototype")
    public class CircleRefA {
        @Autowired
        private CircleRefB circleRefB;
    
        @PostConstruct
        public void init() {
            System.out.println("CircleRefA 创建成功");
        }
    }
    @Component
    @Scope("prototype")
    public class CircleRefB {
        @Autowired
        private CircleRefA circleRefA;
    
        @PostConstruct
        public void init() {
            System.out.println("CircleRefB 创建成功");
        }
    }
    
    Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'circleRefA': Unsatisfied dependency expressed through field 'circleRefB'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'circleRefB': Unsatisfied dependency expressed through field 'circleRefA'; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'circleRefA': Requested bean is currently in creation: Is there an unresolvable circular reference?
    

Spring的三级缓存

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
    // 一级缓存
	/** Cache of singleton objects: bean name --> bean instance */
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

    // 三级缓存
	/** Cache of singleton factories: bean name --> ObjectFactory */
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

    // 二级缓存
	/** Cache of early singleton objects: bean name --> bean instance */
	private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
}

Spring中IOC含有一个DefaultSingletonBeanRegistry.class,其中就有三个map被称为bean创建时的三级缓存;

只有单例的bean会通过三级缓存模型提前存放解决循环依赖的问题,而非单例的bean,每次从容器中获取都是一个新的对象,都会重新创建,所以非单例的bean是没有缓存的,不会将其放入三级缓存模型中;

  • 第一级缓存(单例池)singletonObjects:存放已经经历了完整声明周期的bean对象;
  • 第二级缓存,earlySingletonObjects:存放早期暴露出来的bean对象,Bean的生命周期未结束(属性还未填充完);
  • 第三级缓存,singletonFactories:存放可以生成Bean的工厂;

Spring循环依赖Bean注入IOC全流程

我们的场景和上述场景一样两个单例Bean循环依赖,CircleRefA,CircleRefB;

Spring扫描的顺序是先扫描CircleRefA再扫描CircleRefB;

整体流程

  1. CircleRefA创建对象,并放入三级缓存中;
  2. 欲将CircleRefB注入进CircleRefA中;
  3. 创建CircleRefB对象,并放入三级缓存中;
  4. 欲将CircleRefA注入进CircleRefB中;
  5. 从三级缓存中获取CircleRefA的工厂对象,并由工厂生成CircleRefA对象,放入二级缓存中,移除三级缓存;
  6. 将CircleRefA注入进CircleRefB中;
  7. CircleRefB完成bean创建,移除三级缓存,加入一级缓存;
  8. 将CircleRefB注入进CircleRefA中;
  9. CircleRefA完成bean创建,移除二级缓存,加入一级缓存;
@Component
public class CircleRefA {
    @Autowired
    private CircleRefB circleRefB;

    public CircleRefA() {
        System.out.println("CircleRefA new成功");
    }

    @PostConstruct
    public void init() {
        System.out.println("CircleRefA Bean创建成功");
    }
}
@Component
public class CircleRefB {
    @Autowired
    private CircleRefA circleRefA;

    public CircleRefB() {
        System.out.println("CircleRefB new成功");
    }

    @PostConstruct
    public void init() {
        System.out.println("CircleRefB bean创建成功");
    }
}
1. 创建CircleRefA

在这里插入图片描述

getSingleton(beanName,allowEarlyReference=true)

如上图所示,首先我们根据CircleRefA的db去DefaultSingletonBeanRegistry中获取是否有Bean对象;

这里由于刚开始准备注入,因此三级缓存都没有,返回null;

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // 一级缓存找
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
            // 一级缓存未找到去二级缓存找
            singletonObject = this.earlySingletonObjects.get(beanName);
            if (singletonObject == null && allowEarlyReference) {
                synchronized(this.singletonObjects) { // DDL加锁
                    // 加锁后再去一级缓存找,怕并发已创建
                    singletonObject = this.singletonObjects.get(beanName);
                    if (singletonObject == null) {
                        // 一级缓存未找到去二级缓存找
                        singletonObject = this.earlySingletonObjects.get(beanName);
                        if (singletonObject == null) {
                            // 二级缓存未找到就去三级缓存找
                            ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
                            // 三级缓存找到了,通过工厂创建对象放入二级缓存并删除三级缓存
                            if (singletonFactory != null) {
                                singletonObject = singletonFactory.getObject();
                                this.earlySingletonObjects.put(beanName, singletonObject);
                                this.singletonFactories.remove(beanName);
                            }
                        }
                    }
                }
            }
        }
    // 三个缓存都没有返回NULL,否则返回对象
        return singletonObject;
    }

getSingleton(String beanName, ObjectFactory<?> singletonFactory)

由于未在三级缓存中找到bean对象,doGetBean()这次会再次调用getSingleton(),不过这是个重载方法,这次传入一个创建CircleRefA的工厂;DefaultSingletonBeanRegistry首先再去一级缓存中判断是否已创建CircleRefA,然后再去执行工厂去创建bean;即调用createBean()方法;

// doGetBean()
// 参数1是beanName,参数2是创建该bean的工厂
sharedInstance = this.getSingleton(beanName, () -> {
                        try {
                            // 工厂的实际创建Bean方法
                            return this.createBean(beanName, mbd, args);
                        } catch (BeansException var5) {
                            this.destroySingleton(beanName);
                            throw var5;
                        }
                    });
// DefaultSingletonBeanRegistry
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        synchronized(this.singletonObjects) {
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
                if (this.singletonsCurrentlyInDestruction) {
                    throw new BeanCreationNotAllowedException;
                }
                try {
                    // 调用传入的工厂
                    singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                } catch (IllegalStateException var16) {
                    singletonObject = this.singletonObjects.get(beanName);
                    if (singletonObject == null) {
                        throw var16;
                    }
                } catch (BeanCreationException var17) {
                    throw ex;
                } finally {
                    this.afterSingletonCreation(beanName);
                }

                if (newSingleton) {
                     // 创建好了加入一级缓存中[后续用的]
                    this.addSingleton(beanName, singletonObject);
                }
            }

            return singletonObject;
        }
    }

AbstractAutowireCapableBeanFactory.doCreateBean()

bean的工厂呢,就是在这里创建Bean对象;

  1. 通过createBeanInstance()方法,先把对象new出来,这里使用构造器创建对象BeanUtils.instantiateClass(constructorToUse, new Object[0])

  2. addSingletonFactory()方法,将该对象加入到三级缓存中;

       protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
            Assert.notNull(singletonFactory, "Singleton factory must not be null");
            synchronized(this.singletonObjects) {
                // 判断一级缓存不存在
                if (!this.singletonObjects.containsKey(beanName)) {
                    // 放入三级缓存
                    this.singletonFactories.put(beanName, singletonFactory);
                    // 移除二级缓存(空操作)
                    this.earlySingletonObjects.remove(beanName);
                    this.registeredSingletons.add(beanName);
                }
    
            }
        }
    
  3. 调用populateBean(),注入CircleRefA的属性;

在这里插入图片描述

 protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
        BeanWrapper instanceWrapper = null;
     // 调用构造函数new出来
        if (instanceWrapper == null) {
            instanceWrapper = this.createBeanInstance(beanName, mbd, args);
        }

        Object bean = instanceWrapper.getWrappedInstance();
        Class<?> beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }
     // 加入三级缓存
        boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
        if (earlySingletonExposure) {
            this.addSingletonFactory(beanName, () -> {
                return this.getEarlyBeanReference(beanName, mbd, bean);
            });
        }

        Object exposedObject = bean;

        try {
            // 构造该对象成为一个bean
            this.populateBean(beanName, mbd, instanceWrapper);
            exposedObject = this.initializeBean(beanName, exposedObject, mbd);
        } catch (Throwable var18) {
            throw new BeanCreationException;
        }
    }

AbstractAutowireCapableBeanFactory.populateBean()

这里this.getBeanPostProcessorCache().instantiationAware()总共有4个InstantiationAwareBeanPostProcessor处理器;

在这里插入图片描述

注入CircleRefB是通过最后一个`AutowiredAnnotationBeanPostProcessor处理器去注入的;

 protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
      for(Iterator var9 = this.getBeanPostProcessorCache().instantiationAware.iterator(); var9.hasNext(); pvs = pvsToUse) {
         InstantiationAwareBeanPostProcessor bp =(InstantiationAwareBeanPostProcessor)var9.next();
          // `AutowiredAnnotationBeanPostProcessor进行处理
         pvsToUse = bp.postProcessProperties((PropertyValues)pvs,bw.getWrappedInstance(), beanName);
 }

AutowiredAnnotationBeanPostProcessor.postProcessProperties()

处理器内部主要是获取CirleRefA内部要注入的属性,然后通过构建CirleRefA的元方法,循环将其内部属性进行注入到CircleRefA的内部;

 public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
        InjectionMetadata metadata = this.findAutowiringMetadata(beanName, bean.getClass(), pvs);

        try {
            metadata.inject(bean, beanName, pvs);
            return pvs;
        } catch (BeanCreationException var6) {
            throw var6;
        } catch (Throwable var7) {
            throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", var7);
        }
    }

// InjectionMetadata.inject()
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
        Collection<InjectionMetadata.InjectedElement> checkedElements = this.checkedElements;
        Collection<InjectionMetadata.InjectedElement> elementsToIterate = checkedElements != null ? checkedElements : this.injectedElements;
        if (!((Collection)elementsToIterate).isEmpty()) {
            Iterator var6 = ((Collection)elementsToIterate).iterator();

            while(var6.hasNext()) {
                InjectionMetadata.InjectedElement element = (InjectionMetadata.InjectedElement)var6.next();
                // 属性循环注入 还会调AutowiredAnnotationBeanPostProcessor.inject()
                element.inject(target, beanName, pvs);
            }
        }
    }

// AutowiredAnnotationBeanPostProcessor.inject()
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
            Field field = (Field)this.member;
    		// 创建属性对象
            Object value = this.resolveFieldValue(field, bean, beanName);
    		// 属性注入到对象中
            if (value != null) {
                ReflectionUtils.makeAccessible(field);
                field.set(bean, value);
            }
        }

// 调用resolveFieldValue()
private Object resolveFieldValue(Field field, Object bean, @Nullable String beanName) {
            DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
            desc.setContainingClass(bean.getClass());
            Set<String> autowiredBeanNames = new LinkedHashSet(1);
            Assert.state(AutowiredAnnotationBeanPostProcessor.this.beanFactory != null, "No BeanFactory available");
            TypeConverter typeConverter = AutowiredAnnotationBeanPostProcessor.this.beanFactory.getTypeConverter();
            Object value;
            try {
                // 创建属性对象
                value = AutowiredAnnotationBeanPostProcessor.this.beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
            } catch (BeansException var12) {
                throw new UnsatisfiedDependencyException((String)null, beanName, new InjectionPoint(field), var12);
            }
        }

DependencyDescriptor.resolveCandidate()

resolveDependency() 方法最终会调用到这块,这里又走到了getBean()上,就是紫色的线,至此就轮到CircleRefB的创建;

public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) throws BeansException {
    // 创建getBean()
        return beanFactory.getBean(beanName);
    }
2. 创建CircleRefB

在这里插入图片描述

此时,CircleRefA虽然new成对象,但只放在三级缓存中,然后目前准备将CircleRefB注入到CircleRefA中。因此现在根据紫色的线,走到了getBean(CircleRefB);

这时IOC中也没有CircleRefB,因此,创建CircleRefB的过程和CircleRefA的流程是一模一样

在这里插入图片描述

不过,当CircleRefB要注入CircleRefA时就不一样了;接着,就是紫色的线,CircleRefB准备要注入CircleRefA了

beanFactory.getBean(CircleRefA);

3. CircleRefB获取CircleRefA对象

在这里插入图片描述

此时,CircleRefB虽然new成对象,放入三级缓存中,然后目前准备将CircleRefA注入到CircleRefB中。因此现在根据紫色的线,走到了getBean(CircleRefA);

doGetBean(CircleRefA)

由于三级缓存中有CircleRefA,因此三级缓存中取出CircleRefA的工厂,通过工厂create出CircleRefA对象(还是之前创建的CircleRefA),然后将其加入二级缓存,删除三级缓存并返回;

在这里插入图片描述

// 获取CircleRefA对象
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
        String beanName = this.transformedBeanName(name);
     // 从缓存中取CircleRefA对象
        Object sharedInstance = this.getSingleton(beanName);
        Object beanInstance;
        if (sharedInstance != null && args == null) {
            beanInstance = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
        } 
     return this.adaptBeanInstance(name, beanInstance, requiredType);
 }

此时,CircleRefB要注入的CircleRefA已经从三级缓存中返回,因此回到AutowiredAnnotationBeanPostProcessor.inject()

4. CircleRefB注入CircleRefA对象

目前回退到inject()方法,获取到CircleRefA对象了,准备将其注入进CircleRefB中;图中紫色区域,开始回退;

在这里插入图片描述

AutowiredAnnotationBeanPostProcessor.inject()

获取到后将CircleRefA注入进CircleRefB里。

// AutowiredAnnotationBeanPostProcessor.inject()
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
            Field field = (Field)this.member;
    		// 创建属性对象 此时已获取到CircleRefA
            Object value = this.resolveFieldValue(field, bean, beanName);
    		// CircleRefA注入到CircleRefB中
            if (value != null) {
                ReflectionUtils.makeAccessible(field);
                field.set(bean, value);
            }
        }

注入完成,CircleRefB中的circleRefA已经有对象了(但目前CircleRefA中的CircleRefB还是null);因此回退到DefaultSingletonBeanRegistry.getSingleton()方法;

DefaultSingletonBeanRegistry. getSingleton(String beanName, ObjectFactory<?> singletonFactory)

目前 singletonObject = singletonFactory.getObject()已经将CircleRefB的Bean对象构建完成,此时通过addSingleton()将CircleRefB加入一级缓存中,至此Bean对象已经注入进了IOC中;

// DefaultSingletonBeanRegistry
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        synchronized(this.singletonObjects) {
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
                if (this.singletonsCurrentlyInDestruction) {
                    throw new BeanCreationNotAllowedException;
                }
                try {
                    // 调用传入的工厂
                    singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                } catch (IllegalStateException var16) {
                    singletonObject = this.singletonObjects.get(beanName);
                    if (singletonObject == null) {
                        throw var16;
                    }
                } catch (BeanCreationException var17) {
                    throw ex;
                } finally {
                    this.afterSingletonCreation(beanName);
                }

                if (newSingleton) {
                     // 创建好了加入一级缓存中[后续用的]
                    this.addSingleton(beanName, singletonObject);
                }
            }

            return singletonObject;
        }
    }

DefaultSingletonBeanRegistry.addSingleton()

目前将CircleRefB的bean对象加入一级缓存,并删除二,三级缓存;

在这里插入图片描述

   protected void addSingleton(String beanName, Object singletonObject) {
        synchronized(this.singletonObjects) {
            this.singletonObjects.put(beanName, singletonObject);
            this.singletonFactories.remove(beanName);
            this.earlySingletonObjects.remove(beanName);
            this.registeredSingletons.add(beanName);
        }
    }
5. CircleRefA注入CircleRefB

这里的图和CircleRefB注入CircleRefA的图是一样的,目前CircleRefB已经是一个bean对象了,因此,CircleRefA将CircleRefB注入进去,就是图中紫色的区域,然后开始回退;

在这里插入图片描述

之后注入后也回退到DefaultSingletonBeanRegistry.getSingleton()方法;

DefaultSingletonBeanRegistry. getSingleton(String beanName, ObjectFactory<?> singletonFactory)

这时singletonObject = singletonFactory.getObject();已经将CircleRefA对象创建好了,通过addSingleton()方法将CircleRefA注入进IOC容器中;

// DefaultSingletonBeanRegistry
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        synchronized(this.singletonObjects) {
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
                if (this.singletonsCurrentlyInDestruction) {
                    throw new BeanCreationNotAllowedException;
                }
                try {
                    // 调用传入的工厂
                    singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                } catch (Exception var16) {
                  // doException
                } finally {
                    this.afterSingletonCreation(beanName);
                }
                if (newSingleton) {
                     // 创建好了加入一级缓存中[后续用的]
                    this.addSingleton(beanName, singletonObject);
                }
            }

            return singletonObject;
        }
    }

DefaultSingletonBeanRegistry.addSingleton()

目前将CircleRefA的bean对象加入一级缓存,并删除二,三级缓存;

在这里插入图片描述

   protected void addSingleton(String beanName, Object singletonObject) {
        synchronized(this.singletonObjects) {
            this.singletonObjects.put(beanName, singletonObject);
            this.singletonFactories.remove(beanName);
            this.earlySingletonObjects.remove(beanName);
            this.registeredSingletons.add(beanName);
        }
    }

至此,CircleRefA和CircleRefB已经注入到IOC容器了。

被AOP代理类循环依赖的全过程

强调下,大体流程和上面的图一致,就是底下有细微差距;

情况1:先扫描被代理类

背景:People.class被AopComponent代理,先于ZBird.class扫描

@Aspect
@Component
public class AopComponent {
    @Pointcut("execution(* com.test.bean.People.*(..))")
    public void methodPointcut() {
    }

    @Around("methodPointcut()")
    public void init(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("进入AOP");
        pjp.proceed();
        System.out.println("离开AOP");
    }
}
// 被代理的类People
@Component
public class People {

    @Autowired
    private ZBird ZBird;

    public void speak() {
        System.out.println("hello, I am people");
    }
}
// 未被代理类ZBird
@Component
public class ZBird {
    @Autowired
    private People people;

    public void speak() {
        System.out.println("hello, I am Bird");
    }
}
  1. 创建People类对象,放入三级缓存中;

  2. 注入People类中的属性Zbird;

  3. 创建Zbird类对象,放入三级缓存中;

  4. 注入Zbird类中的属性People;

  5. 从三级缓存中取出People的工厂,工厂创建的是代理对象People并放入二级缓存中;

    由图可得,ZBird取三级缓存中的时候,实际上是返回了AOP创建的代理对象,并将代理对象放入了二级缓存中;其中这个创建代理对象的函数,每次调用这个工厂都会返回一个新的代理对象;

    其中,AbstractAutoProxyCreator.class中有一个earlyProxyRefrences字段,他类似一个缓存,避免重复通过工厂创建代理对象;以下是循环引用的举例说明:

    ? 当AOP代理的类先扫描时,会通过getEarlyBeanReference()创建代理对象,后面initializeBean()时,再次调用postProcessAfterInitialization()由于有缓存,不会再创建对应代理类;

    ? 当AOP代理的类后被扫描时,会直接由initializeBean()调用postProcessAfterInitialization()创建代理对象;

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

  6. 将代理对象People注入进Zbird中;

    在这里插入图片描述

  7. Zbird移除三级缓存,放入一级缓存;

  8. People类中注入Zbird;

  9. initializeBean(People类)后再次getSingleton()将二级缓存的People代理返回;

    从图中紫色部分可以看到,当people类完成Bean生命周期的时候,people对象注入了ZBird,ZBird中注入的是代理People对象;

    红色部分是,spring又从工厂中将people的二级缓存取出,这里是代理对象,因此返回并注入进一级缓存的是代理对象People;

    这里出现了个问题,最终从IOC中取People后,无法得到被注入的对象ZBird,因为代理对象这里是null;

    在这里插入图片描述

  10. 将代理对象People放入一级缓存;

情况2:后扫描被代理类
@Aspect
@Component
public class AopComponent {
    @Pointcut("execution(* com.test.bean.People.*(..))")
    public void methodPointcut() {
    }

    @Around("methodPointcut()")
    public void init(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("进入AOP");
        pjp.proceed();
        System.out.println("离开AOP");
    }
}
// 被代理的类People
@Component
public class People {

    @Autowired
    private Bird bird;

    public void speak() {
        System.out.println("hello, I am people");
    }
}
// 未被代理类Bird
@Component
public class Bird {
    @Autowired
    private People people;

    public void speak() {
        System.out.println("hello, I am Bird");
    }
}
  1. 创建Bird对象,并放入三级缓存中;

  2. 欲将People对象注入进Bird中;

  3. 创建People对象,并放入三级缓存中;

  4. 欲将Bird对象注入进People中;

  5. 从三级缓存中取出Bird对象,并放入二级缓存中;

  6. 将Bird对象注入进People中;

  7. 调用initializeBean(People)返回代理对象;

    在这里插入图片描述

  8. 由于二级缓存没有People对象,因此直接将代理对象People返回并注入进一级缓存中;

  9. People代理对象注入进Bird;

  10. Bird初始化后,移除二级缓存,放入一级缓存;

Spring Bean无代理是加入IOC容器流程

  1. 创建Bean对象,并加入三级缓存;
  2. 注入Bean中的属性字段;
  3. Bean完成initBean();
  4. 将Bean加入一级缓存并移除三级缓存;

Spring Bean被AOP代理是加入IOC容器流程

  1. 创建Bean对象,并加入三级缓存;
  2. 注入Bean中的属性字段;
  3. Bean完成initBean(),并由AOP处理器返回代理对象Bean;
  4. 将代理对象Bean加入一级缓存并移除三级缓存;
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-10-08 11:39:38  更:2021-10-08 11:40:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:24:49-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码