四站合一网站建设公司,wordpress插件进销存,电子商务网站建设源码,漳州最专业的网站建设4.Spring【Java面试第三季】前言推荐4.Spring27_Aop的题目说明要求Spring的AOP顺序AOP常用注解面试题28_spring4下的aop测试案例业务类新建一个切面类MyAspect并为切面类新增两个注解#xff1a;spring4springboot1.5.9pom测试类29_spring4下的aop测试结果aop正常顺序异常顺序…
4.Spring【Java面试第三季】前言推荐4.Spring27_Aop的题目说明要求Spring的AOP顺序AOP常用注解面试题28_spring4下的aop测试案例业务类新建一个切面类MyAspect并为切面类新增两个注解spring4springboot1.5.9pom测试类29_spring4下的aop测试结果aop正常顺序异常顺序30_spring5下的aop测试spring5springboot2.3.3pom测试类aop正常顺序异常顺序结论31_spring循环依赖题目说明Spring的循环依赖恶心的大厂面试题什么是循环依赖两种注入方式对循环依赖的影响32_spring循环依赖纯java代码验证案例spring容器循环依赖报错演示BeanCurrentlylnCreationException循环依赖现象在Spring容器中注入依赖的对象有2种情况构造器方式注入依赖以set方式注入依赖33_spring循环依赖bug演示重要code案例演示code-java基础编码spring容器重要结论(spring内部通过3级缓存来解决循环依赖)34_spring循环依赖debug前置知识循环依赖Debug-困难请坚持实例化/初始化3个Map和四大方法总体相关对象A/B两对象在三级缓存中的迁移说明spring循环依赖debug源码39_spring循环依赖小总结总结spring是如何解决的循环依赖?解释Debug的步骤---Spring解决循环依赖过程最后前言
2023-2-3 13:51:54
以下内容源自 【尚硅谷Java大厂面试题第3季跳槽必刷题目必扫技术盲点周阳主讲-哔哩哔哩】 仅供学习交流使用
推荐
Java开发常见面试题详解LockSupportAQSSpring循环依赖Redis
4.Spring 27_Aop的题目说明要求 Spring的AOP顺序
AOP常用注解
Before 前置通知目标方法之前执行After 后置通知目标方法之后执行始终执行)AfterReturning 返回后通知执行方法结束前执行(异常不执行)AfterThrowing 异常通知出现异常时候执行Around 环绕通知环绕目标方法执行
面试题 你肯定知道spring那说说aop的全部通知顺序springboot或springboot2(spring4-spring5)对aop的执行顺序影响 说说你使用AOP中碰到的坑? 28_spring4下的aop测试案例 业务类
接口CalcService接口实现类CalcServicelmpl新加Service想在除法方法前后置入各种通知引入切面编程
新建Maven工程pom.xml如下
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersionparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion1.5.9.RELEASE/versionrelativePath//parentgroupIdcom.example/groupIdartifactIdspring4_aop/artifactIdversion0.0.1-SNAPSHOT/versionnamespring4_aop/namedescriptionspring4_aop/descriptionpropertiesjava.version8/java.version/propertiesdependencies!-- web --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!-- Spring Boot AOP技术--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scopeexclusionsexclusiongroupIdorg.junit.vintage/groupIdartifactIdjunit-vintage-engine/artifactId/exclusion/exclusions/dependency/dependenciesbuildpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactId/plugin/plugins/build/project
启动类
package com.example.spring4_aop;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;SpringBootApplication
public class Spring4AopApplication {public static void main(String[] args) {SpringApplication.run(Spring4AopApplication.class, args);}}
接口CalcService
package com.example.spring4_aop.spring.aop;public interface CalcService {public int div(int x, int y);
}
接口实现类CalcServiceImpl新加Service
package com.example.spring4_aop.spring.aop;import org.springframework.stereotype.Service;Service
public class CalcServiceImpl implements CalcService {Overridepublic int div(int x, int y) {int result x / y;System.out.println(CalcServiceImpl被调用计算结果为 result);return result;}
}
新建一个切面类MyAspect并为切面类新增两个注解
Aspect 指定一个类为切面类Component 纳入Spring容器管理code
package com.example.spring4_aop.spring.aop;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;Aspect
Component
public class MyAspect {Before(execution(public int com.example.spring4_aop.spring.aop.CalcServiceImpl.*(..)))public void beforeNotify() {System.out.println(********Before我是前置通知);}After(execution(public int com.example.spring4_aop.spring.aop.CalcServiceImpl.*(..)))public void afterNotify() {System.out.println(********After我是后置通知);}AfterReturning(execution(public int com.example.spring4_aop.spring.aop.CalcServiceImpl.*(..)))public void afterReturningNotify() {System.out.println(********AfterReturning我是返回后通知);}AfterThrowing( execution(public int com.example.spring4_aop.spring.aop.CalcServiceImpl.*(..)))public void afterThrowingNotify() {System.out.println(********AfterThrowing我是异常通知);}Around( execution(public int com.example.spring4_aop.spring.aop.CalcServiceImpl.*(..)))public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {Object retvalue null;System.out.println(我是环绕通知之前AAA);retvalue proceedingJoinPoint.proceed();System.out.println(我是环绕通知之后BBB);return retvalue ;}
}
spring4springboot1.5.9
pom parentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion1.5.9.RELEASE/versionrelativePath//parent测试类
package com.example.spring4_aop;import javax.annotation.Resource;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.SpringBootVersion;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.SpringVersion;
import org.springframework.test.context.junit4.SpringRunner;import com.example.spring4_aop.spring.aop.CalcService;SpringBootTest
RunWith(SpringRunner.class)
public class AopTest {Resourceprivate CalcService calcService;Testpublic void testAop4() {System.out.println(String.format(Spring Verision : %s, Sring Boot Version : %s., //SpringVersion.getVersion(), SpringBootVersion.getVersion()));calcService.div(10, 2);}
} 29_spring4下的aop测试结果 Spring Verision : 4.3.13.RELEASE, Sring Boot Version : 1.5.9.RELEASE.
我是环绕通知之前AAA
********Before我是前置通知
CalcServiceImpl被调用计算结果为5
我是环绕通知之后BBB
********After我是后置通知
********AfterReturning我是返回后通知修改测试类让其抛出算术异常类
package com.example.spring4_aop;import javax.annotation.Resource;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.SpringBootVersion;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.SpringVersion;
import org.springframework.test.context.junit4.SpringRunner;import com.example.spring4_aop.spring.aop.CalcService;SpringBootTest
RunWith(SpringRunner.class)
public class AopTest {Resourceprivate CalcService calcService;Testpublic void testAop4() {System.out.println(String.format(Spring Verision : %s, Sring Boot Version : %s., //SpringVersion.getVersion(), SpringBootVersion.getVersion()));// calcService.div(10, 2);calcService.div(10, 0);//将会抛出异常}
}
输出结果
Spring Verision : 4.3.13.RELEASE, Sring Boot Version : 1.5.9.RELEASE.
我是环绕通知之前AAA
********Before我是前置通知
********After我是后置通知
********AfterThrowing我是异常通知java.lang.ArithmeticException: / by zeroaop正常顺序异常顺序 正常情况下Before前置通知-----After后置通知-----AfterRunning正常返回异常情况下Before前置通知-----After后置通知-----AfterThrowing方法异常 30_spring5下的aop测试 spring5springboot2.3.3
pom parentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactId
!-- version1.5.9.RELEASE/version--version2.3.3.RELEASE/versionrelativePath//parent测试类
package com.example.spring4_aop;import javax.annotation.Resource;import org.junit.jupiter.api.Test;
import org.springframework.boot.SpringBootVersion;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.SpringVersion;
import org.springframework.test.context.junit4.SpringRunner;import com.example.spring4_aop.spring.aop.CalcService;SpringBootTestpublic class AopTest {Resourceprivate CalcService calcService;Testpublic void testAop4() {System.out.println(String.format(Spring Verision : %s, Sring Boot Version : %s., //SpringVersion.getVersion(), SpringBootVersion.getVersion()));// calcService.div(10, 2);calcService.div(10, 0);//将会抛出异常}Testpublic void testAop5() {System.out.println(String.format(Spring Verision : %s, Sring Boot Version : %s., //SpringVersion.getVersion(), SpringBootVersion.getVersion()));calcService.div(10, 2);// calcService.div(10, 0);//将会抛出异常}
}
Spring Verision : 5.2.8.RELEASE, Sring Boot Version : 2.3.3.RELEASE.
我是环绕通知之前AAA
********Before我是前置通知
CalcServiceImpl被调用计算结果为5
********AfterReturning我是返回后通知
********After我是后置通知
我是环绕通知之后BBB修改测试类让其抛出算术异常类
package com.example.spring4_aop;import javax.annotation.Resource;import org.junit.jupiter.api.Test;
import org.springframework.boot.SpringBootVersion;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.SpringVersion;
import org.springframework.test.context.junit4.SpringRunner;import com.example.spring4_aop.spring.aop.CalcService;SpringBootTestpublic class AopTest {Resourceprivate CalcService calcService;Testpublic void testAop4() {System.out.println(String.format(Spring Verision : %s, Sring Boot Version : %s., //SpringVersion.getVersion(), SpringBootVersion.getVersion()));// calcService.div(10, 2);calcService.div(10, 0);//将会抛出异常}Testpublic void testAop5() {System.out.println(String.format(Spring Verision : %s, Sring Boot Version : %s., //SpringVersion.getVersion(), SpringBootVersion.getVersion()));// calcService.div(10, 2);calcService.div(10, 0);//将会抛出异常}
}
输出结果
Spring Verision : 5.2.8.RELEASE, Sring Boot Version : 2.3.3.RELEASE.
我是环绕通知之前AAA
********Before我是前置通知
********AfterThrowing我是异常通知
********After我是后置通知java.lang.ArithmeticException: / by zeroaop正常顺序异常顺序
同上结果
结论 31_spring循环依赖题目说明 Spring的循环依赖
恶心的大厂面试题
你解释下spring中的三级缓存三级缓存分别是什么三个Map有什么异同什么是循环依赖请你谈谈看过spring源码吗一般我们说spring容器是什么如何检测是否存在循环依赖实际开发中见过循环依赖的异常吗多例的情况下循环依赖问题为什么无法解决。。。
什么是循环依赖 多个bean之间相互依赖形成了一个闭环。比如A依赖于B、B依赖于C、C依赖于A。 代码 通常来说如果问Spring容器内部如何解决循环依赖一定是指默认的单例Bean中属性互相引用的场景。
两种注入方式对循环依赖的影响
https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#spring-core 循环依赖官网说明 结论 我们AB循环依赖问题只要A的注入方式是setter且singleton 就不会有循环依赖问题。 32_spring循环依赖纯java代码验证案例 spring容器循环依赖报错演示BeanCurrentlylnCreationException
循环依赖现象在Spring容器中注入依赖的对象有2种情况
构造器方式注入依赖
code
serviceA
Component
public class ServiceA{private ServiceB serviceB;public ServiceA(ServiceB serviceB){this.serviceB serviceB;}
}
serviceB
Component
public class ServiceB{private ServiceA serviceA;public ServiceB(ServiceA serviceA){this.serviceA serviceA;}
}
ClientConstructor
public class ClientConstructor{public static void main(String[] args){new ServiceA(new ServiceB(new ServiceA()));//这会抛出编译异常}
}
结论
构造器循环依赖是无法解决的你想让构造器注入支持循环依赖是不存在的
以set方式注入依赖
code
ServiceAA
Component
public class ServiceAA{private ServiceBB serviceBB;public void setServiceBB(ServiceBB serviceBB){this.serviceBB serviceBB;System.out.println(A里面设置了B);}
}
ServiceBB
Component
public class ServiceBB{private ServiceAA serviceAA;public void setServiceAA(ServiceAA serviceAA){this.serviceAA serviceAA;System.out.println(B里面设置了A);}
}
ClientSet
public class ClientSet{public static void main(String[] args){//创建serviceAAServiceAA a new ServiceAA();//创建serviceBBServiceBB b new ServiceBB();//将serviceA入到serviceB中b.setServiceAA(a);//将serviceB法入到serviceA中a.setServiceBB(b);}
}
输出结果
B里面设置了A
A里面设置了B 33_spring循环依赖bug演示 重要code案例演示
code-java基础编码
A
package com.example.spring4_aop.spring;public class A {private B b;public B getB() {return b;}public void setB(B b) {this.b b;}public A() {System.out.println(---A created success);}
}
B
package com.example.spring4_aop.spring;public class B {private A a;public A getA() {return a;}public void setA(A a) {this.a a;}public B() {System.out.println(---B created success);}
}
ClientCode
package com.example.spring4_aop.spring;public class ClientCode {public static void main(String[] args) {A anew A();B bnew B();b.setA(a);a.setB(b);}
}
测试结果
---A created success
---B created successspring容器
默认的单例(singleton)的场景是支持循环依赖的不报错原型(Prototype)的场景是不支持循环依赖的会报错步骤 applicationContext.xml默认单例修改为原型scopeprototypeClientspringContainer循环依赖异常
applicationContext.xml
?xml version1.0 encodingUTF-8 ?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xmlns:phttp://www.springframework.org/schema/pxmlns:contexthttp://www.springframework.org/schema/contextxmlns:aophttp://www.springframework.org/schema/aop xmlns:txhttp://www.springframework.org/schema/txxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-4.0.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.0.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-4.0.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-4.0.xsdbean ida classcom.example.spring4_aop.spring.Aproperty nameb refb/property/beanbean idb classcom.example.spring4_aop.spring.Bproperty namea refa/property/bean/beans
ClientSpringContainer
package com.example.spring4_aop.spring;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class ClientSpringContainer {public static void main(String[] args) {ApplicationContext context new ClassPathXmlApplicationContext(applicationContext.xml);A a context.getBean(a, A.class);B b context.getBean(b, B.class);}
}
输出结果
15:29:16.316 [main] DEBUG org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext61064425
15:29:16.552 [main] DEBUG org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loaded 2 bean definitions from class path resource [applicationContext.xml]
15:29:16.607 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean a
---A created success
15:29:16.626 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean b
---B created success原型(Prototype)的场景是不支持循环依赖的会报错
applicationContext.xml bean ida classcom.example.spring4_aop.spring.A scopeprototypeproperty nameb refb/property/beanbean idb classcom.example.spring4_aop.spring.B scopeprototypeproperty namea refa/property/bean输出结果
15:33:03.481 [main] DEBUG org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext61064425
15:33:03.669 [main] DEBUG org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loaded 2 bean definitions from class path resource [applicationContext.xml]
---A created success
---B created success
Exception in thread main org.springframework.beans.factory.BeanCreationException: Error creating bean with name a defined in class path resource [applicationContext.xml]: Cannot resolve reference to bean b while setting bean property b; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name b defined in class path resource [applicationContext.xml]: Cannot resolve reference to bean a while setting bean property a; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name a: Requested bean is currently in creation: Is there an unresolvable circular reference?Exception in thread main org.springframework.beans.factory.BeanCreationException:Error creating bean with name a: Requested bean is currently in creation: Is there an unresolvable circular reference?
重要结论(spring内部通过3级缓存来解决循环依赖)
DefaultSingletonBeanRegistry
只有单例的bean会通过三级缓存提前暴露来解决循环依赖的问题而非单例的bean每次从容器中获取都是一个新的对象都会重新创建所以非单例的bean是没有缓存的不会将其放到三级缓存中。
第一级缓存也叫单例池singletonObjects存放已经经历了完整生命周期的Bean对象。
第二级缓存earlySingletonObjects存放早期暴露出来的Bean对象Bean的生命周期未结束属性还未填充完。)
第三级缓存MapString, ObjectFactory? singletonFactories存放可以生成Bean的工厂。
package org.springframework.beans.factory.support;...public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {.../** Cache of singleton objects: bean name to bean instance. */private final MapString, Object singletonObjects new ConcurrentHashMap(256);/** Cache of singleton factories: bean name to ObjectFactory. */private final MapString, ObjectFactory? singletonFactories new HashMap(16);/** Cache of early singleton objects: bean name to bean instance. */private final MapString, Object earlySingletonObjects new HashMap(16);...} 34_spring循环依赖debug前置知识 循环依赖Debug-困难请坚持
实例化/初始化 实例化 内存中申请一块内存空间租赁好房子自己的家当还未搬来。 初始化属性填充 完成属性的各种赋值装修家具家电进场。
3个Map和四大方法总体相关对象 第一层singletonObjects存放的是已经初始化好了的Bean,
第二层earlySingletonObjects存放的是实例化了但是未初始化的Bean,
第三层singletonFactories存放的是FactoryBean。假如A类实现了FactoryBean,那么依赖注入的时候不是A类而是A类产生的Bean
package org.springframework.beans.factory.support;...public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {.../** 单例对象的缓存:bean名称—bean实例即:所谓的单例池。表示已经经历了完整生命周期的Bean对象第一级缓存*/private final MapString, Object singletonObjects new ConcurrentHashMap(256);/**早期的单例对象的高速缓存: bean名称—bean实例。表示 Bean的生命周期还没走完Bean的属性还未填充就把这个 Bean存入该缓存中也就是实例化但未初始化的 bean放入该缓存里第二级缓存*/private final MapString, Object earlySingletonObjects new HashMap(16);/**单例工厂的高速缓存:bean名称—ObjectFactory表示存放生成 bean的工厂第三级缓存*/private final MapString, ObjectFactory? singletonFactories new HashMap(16);...}
A/B两对象在三级缓存中的迁移说明
1.A创建过程中需要B于是A将自己放到三级缓存里面去实例化B。
2.B实例化的时候发现需要A于是B先查一级缓存没有再查二级缓存还是没有再查三级缓存找到了A然后把三级缓存里面的这个A放到二级缓存里面并删除三级缓存里面的A。
3.B顺利初始化完毕将自己放到一级缓存里面此时B里面的A依然是创建中状态)然后回来接着创建A此时B已经创建结束直接从一级缓存里面拿到B然后完成创建并将A自己放到一级缓存里面。
FunctionalInterface
public interface ObjectFactoryT {T getObject() throws BeansException;} spring循环依赖debug源码 跳转 spring循环依赖debug源码 39_spring循环依赖小总结 总结spring是如何解决的循环依赖? 解释
Spring创建 bean主要分为两个步骤创建原始bean对象接着去填充对象属性和初始化
每次创建 bean之前我们都会从缓存中查下有没有该bean因为是单例只能有一个
当我们创建 beanA的原始对象后并把它放到三级缓存中接下来就该填充对象属性了这时候发现依赖了beanB接着就又去创建beanB同样的流程创建完beanB填充属性时又发现它依赖了beanA又是同样的流程
不同的是
这时候可以在三级缓存中查到刚放进去的原始对象beanA.所以不需要继续创建用它注入 beanB完成 beanB的创建
既然 beanB创建好了所以 beanA就可以完成填充属性的步骤了接着执行剩下的逻辑闭环完成 Spring解决循环依赖依靠的是Bean的中间态这个概念而这个中间态指的是已经实例化但还没初始化的状态—半成品。 实例化的过程又是通过构造器创建的如果A还没创建好出来怎么可能提前曝光所以构造器的循环依赖无法解决。”对
Spring为了解决单例的循坏依赖问题使用了三级缓存 其中一级缓存为单例池(singletonObjects)。 二级缓存为提前曝光对象(earlySingletonObjects)。 三级级存为提前曝光对象工厂(singletonFactories) 。
假设A、B循环引用实例化A的时候就将其放入三级缓存中接着填充属性的时候发现依赖了B同样的流程也是实例化后放入三级缓存接着去填充属性时又发现自己依赖A这时候从缓存中查找到早期暴露的A没有AOP代理的话直接将A的原始对象注入B完成B的初始化后进行属性填充和初始化这时候B完成后就去完成剩下的A的步骤如果有AOP代理就进行AOP处理获取代理后的对象A注入B走剩下的流程。
Debug的步骤—Spring解决循环依赖过程 调用doGetBean()方法想要获取beanA于是调用getSingleton()方法从缓存中查找beanA在getSingleton()方法中从一级缓存中查找没有返回nulldoGetBean()方法中获取到的beanA为null于是走对应的处理逻辑调用getSingleton()的重载方法参数为ObjectFactory的)在getSingleton()方法中先将beanA_name添加到一个集合中用于标记该bean正在创建中。然后回调匿名内部类的creatBean方法进入AbstractAutowireCapableBeanFactory#ndoCreateBean先反射调用构造器创建出beanA的实例然后判断:是否为单例、是否允许提前暴露引用(对于单例一般为true)、是否正在创建中即是否在第四步的集合中。判断为true则将beanA添加到【三级缓存】中对beanA进行属性填充此时检测到beanA依赖于beanB于是开始查找beanB调用doGetBean()方法和上面beanA的过程一样到缓存中查找beanB没有则创建然后给beanB填充属性此时 beanB依赖于beanA调用getSingleton()获取beanA依次从一级、二级、三级缓存中找此时从三级缓存中获取到beanA的创建工厂通过创建工厂获取到singletonObject此时这个singletonObject指向的就是上面在doCreateBean()方法中实例化的beanA这样beanB就获取到了beanA的依赖于是beanB顺利完成实例化并将beanA从三级缓存移动到二级缓存中随后beanA继续他的属性填充工作此时也获取到了beanBbeanA也随之完成了创建回到getsingleton()方法中继续向下执行将beanA从二级缓存移动到一级缓存中
最后
2023-2-3 21:23:12
这篇博客能写好的原因是站在巨人的肩膀上
这篇博客要写好的目的是做别人的肩膀
开源为爱发电
学习为我而行