概述
Spring Aop
spring = lOC + AOP +TX
spring的aop顺序
新建一个切面类MyAspect
并为切面类新增两个注惫
spring循环依赖
Spring4+springboot1.5.9
Spring5+springboot2.3.3
回顾
Aop 5大通知
- @Before
- 前置通知:目标方法之前执行
- @After
- 后置通知:目标方法之后后执行(始终执行)
- @AfterReturning
- 返回后通知:执行方法结束前执行(异常不执行)
- @AfterThrowing
- 异常通知:出现异常时候执行
- @Around
- 环绕通知:环绕目标方法执行
版本介绍
-
2023年2月2日。
-
现在2.X版本为:2.7.8,使用Spring-core 5.3.25
-
现在boot 3.0.2,使用Spring-core 6.0.4
aspect
英
/ˈæspekt/
n.
方面,特色;朝向,方位;外表,外观;(动词的)体
对比spring 4
导入aop包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
编写切面和 Service
@Aspect
@Component
public class MyAspect {
@Before("execution(public int com.atguigu.interview1024.service.CalcServiceImpl.*(..))")
public void beforeNotify() {
System.out.println("@Before 前置通知");
}
@After("execution(public int com.atguigu.interview1024.service.CalcServiceImpl.*(..))")
public void afterNotify() {
System.out.println("@After 后置通知");
}
@AfterReturning("execution(public int com.atguigu.interview1024.service.CalcServiceImpl.*(..))")
public void afterReturningNotify() {
System.out.println("@AfterReturning 返回后通知");
}
@AfterThrowing("execution(public int com.atguigu.interview1024.service.CalcServiceImpl.*(..))")
public void afterThrowingNotify() {
System.out.println("@AfterThrowing 异常通知");
}
@Around("execution(public int com.atguigu.interview1024.service.CalcServiceImpl.*(..))")
public Object aroundNotify(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("@Around 环绕通知之前");
Object proceed = pjp.proceed();
System.out.println("@Around 环绕通知之后,对象为:"+proceed);
return proceed;
}
}
@Service
public class CalcServiceImpl implements CalcService {
@Override
public int div(int x, int y) {
int r = x / y;
System.out.println("本次运算的结果为:" + r);
return r;
}
}
public interface CalcService {
public int div(int x, int y);
}
Aspect指定一个类为切面类
Component纳入spring容器管理
演示Spring4
- boot改为
<version>1.5.9.RELEASE</version>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-access</artifactId>
<!--<version>1.1.11</version> 老师用的是1.1.3-->
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
Spring4测试类
@SpringBootTest
@RunWith(SpringRunner.class)
public class TestAop {
@Resource
private CalcService calcService;
@Test
public void testAop() {
System.out.println("spring版本:" + SpringVersion.getVersion());
System.out.println("springBoot版本" + SpringBootVersion.getVersion());
System.out.println();
System.out.println("测试类打印结果了:" + calcService.div(10, 2));
}
}
正常和异常运行
正常
spring版本:4.3.13.RELEASE
springBoot版本1.5.9.RELEASE
@Around 环绕通知之前
@Before 前置通知
本次运算的结果为:5
@Around 环绕通知之后,对象为:5
@After 后置通知
@AfterReturning 返回后通知
测试类打印结果了:5
-
@Around 环绕通知之前
- @Before 前置通知
- 本次运算的结果为:5
-
@Around 环绕通知之后,对象为:5
-
@After 后置通知
-
@AfterReturning 返回后通知
总结:环绕 了 前置和本方法。然后:后置,返回后通知。
- Before
- Before + 方法,被 环绕通知 包裹
- After
- AfterReturning
异常执行
@Around 环绕通知之前
@Before 前置通知
要调用div方法了
@After 后置通知
@AfterThrowing 异常通知
java.lang.ArithmeticException: / by zero
- 环绕前
- 前置
- 执行方法
- 后置
- 异常通知
没有 环绕后的逻辑,没有 返回后通知
- Before
- Before + 方法,被 环绕通知 包裹,注意:没有环绕后通知。
- After
- AfterThrowing
try{
@Before 之前
method.invoke(obj,args);
@AfterReturning 执行后返回
}catch(){
@AfterThrowing 抛出异常
}finally{
@After 注意:这里还 try 还是有区别的,是先执行 @After,在执行 @AfterThrowing
}
Spring5和6。After 在最后。
- logback 的都去掉
<version>2.3.4.RELEASE</version> #老师的为 2.3.3.RELEASE
测试类
import org.junit.jupiter.api.Test; #测试使用这个包
@SpringBootTest
public class TestAop {
@Resource
private CalcService calcService;
@Test
public void testAop() {
System.out.println("spring版本:" + SpringVersion.getVersion());
System.out.println("springBoot版本" + SpringBootVersion.getVersion());
System.out.println();
System.out.println("测试类打印结果了:" + calcService.div(10, 0));
}
}
正常执行
spring版本:5.2.9.RELEASE
springBoot版本2.3.4.RELEASE
@Around 环绕通知之前
@Before 前置通知
要调用div方法了
本次运算的结果为:5
@AfterReturning 返回后通知
@After 后置通知
@Around 环绕通知之后,对象为:5
测试类打印结果了:5
-
Before
-
执行
-
AfterReturning 返回后通知。先执行是 返回后通知,4.0是 先执行后置通知
-
After 返回后通知
- 环绕通知 在最开始和最结束执行。4.0是在 后置通知之前执行。
-
完全遵守, try catch finally
try{
1. @Before 之前
2. method.invoke(obj,args);
3. @AfterReturning 执行后返回
}catch(){
@AfterThrowing 抛出异常
}finally{
4. @After
}
spring版本:6.0.4
springBoot版本3.0.2
@Around 环绕通知之前
@Before 前置通知
要调用div方法了
本次运算的结果为:5
@AfterReturning 返回后通知
@After 后置通知
@Around 环绕通知之后,对象为:5
测试类打印结果了:5
异常执行
spring版本:5.2.9.RELEASE
springBoot版本2.3.4.RELEASE
@Around 环绕通知之前
@Before 前置通知
要调用div方法了
@AfterThrowing 异常通知
@After 后置通知
java.lang.ArithmeticException: / by zero
- Before
- 执行
- AfterThrowing
- After
- 环绕通知,依然是 在最开始执行,只执行一个。
同样是:try catch finally
你肯定知道spring,那说说aop的全部通知顺序springboot或springboot2对aop的执行顺序影响?
Spring4 === > Spring5
AOP的全部执行顺序,有哪些坑,你遇到过》
对于aop的执行顺序是不同的
boot1 ====》boot2
Spring 循环依赖
面试题
什么是循环依赖
两种注入方式对循环依赖的影响
spring容器循环依赖报错演示BeanCurrentlylnCreationException
循环依赖Debug-困难,请坚持
总结Spring是如何解决的循环依赖?
你解释下spring中的三级缓存?
三级缓存分别是什么?三个Map有什么异同?
-什么是循环依赖?请你谈谈?看过spring源码吗?一般我们说的spring容器是什么?
如何检测是否存在循环依赖?实际开发中见过循环依赖的异常吗?
多例的情况下,循环依赖问题为什么无法解决?
- 重要结论(spring内部通过3级缓存来解决循环依赖)
循环依赖
多个bean之间相互依赖,形成了一个闭环
比如:A依赖于B、B依赖于c、c依赖于A
通常来说,如果问spring容器内部如何解决循环依赖,一定是指默认的单例Bean中,属性互相引用的场景
public class T1 {
static class A {
B b;
}
static class B {
C c;
}
static class C {
A a;
}
public static void main(String[] args) {
A a = new A();//可以运行
}
}
- 文档官网
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#spring-core
- 循环依赖
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-dependency-resolution
-
Circular dependencies
-
构造器方式注入依赖
-
以set方式注入依赖
-
属性+注解注入
构造方法注入,可能出现 循环依赖,(报错)
- A 里需要B,B里需要 A
- 抛出异常:BeanCurrentlyInCreationException
避免构造注入,使用 Set 注入,是可以的。(正常)
我们AB循环依赖问题只要A的注入方式是setter且singleton ,
就不会有循环依赖问题
模拟BeanCurrentlyInCreationException
构造方法注入
构造器循环依赖是无法解决的
你想让构造器注入支持循环依赖,是不存在的
- A 要 B ,B 要 A,无尽头
new ServiceA(new ServiceB(xxxx));
循环依赖
如果您主要使用构造函数注入,则可能会创建无法解决的循环依赖场景。
例如:A类通过构造函数注入需要B类的实例,B类通过构造函数注入需要A类的实例。如果将类 A 和 B 的 bean 配置为相互注入,则 Spring IoC 容器会在运行时检测到此循环引用,并抛出一个 BeanCurrentlyInCreationException
.
一种可能的解决方案是编辑某些类的源代码,使其由设置器而不是构造器配置。或者,避免构造函数注入并仅使用 setter 注入。也就是说,虽然不推荐,但是可以通过setter注入来配置循环依赖。
与典型情况(没有循环依赖)不同,bean A 和 bean B 之间的循环依赖强制其中一个 bean 在完全初始化之前注入到另一个 bean(经典的先有鸡还是先有蛋的场景)。
- 启动后报错
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'serviceA': Requested bean is currently in creation: Is there an unresolvable circular reference?
@Component
public class ServiceA {
private ServiceB serviceB;
public ServiceA(ServiceB b) {
this.serviceB = b;
}
}
@Component
public class ServiceB {
private ServiceA serviceA;
public ServiceB(ServiceA a) {
this.serviceA = a;
}
}
使用 set方法没问题
@Component
public class ServiceA {
private ServiceB serviceB;
public void setServiceB(ServiceB b) {
this.serviceB = b;
System.out.println("A 里设置了 B");
}
}
@Component
public class ServiceB {
private ServiceA serviceA;
public void setServiceA(ServiceA a) {
this.serviceA = a;
System.out.println("B 里设置了 A");
}
}
@Autowired
private ServiceA serviceA;
@Autowired
private ServiceB serviceB;
@Test
public void testAop() {
serviceA.setServiceB(serviceB);
serviceB.setServiceA(serviceA);
}
A 里设置了 B
B 里设置了 A
//用 new 也是 可以的
使用Spring配置文件测试
A和B两个类依赖类
@Data
public class A {
private B b;
public A() {
System.out.println("A 被创建了");
}
}
@Data
public class B {
private A a;
public B() {
System.out.println("B被创建了");
}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd">
<bean id="a" class="com.atguigu.interview1024.depend.A" lazy-init="true">
<property name="b" ref="b"></property>
</bean>
<bean id="b" class="com.atguigu.interview1024.depend.B" lazy-init="true">
<property name="a" ref="a"></property>
</bean>
</beans>
测试类
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//就算不使用,也会默认 创建 这两个类。两个都加 lazy-init="true",就不会默认创建了
/*A a = context.getBean("a", A.class);
B b = context.getBean("b", B.class);*/
13:28:37.315 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'a'
A 被创建了
13:28:37.327 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'b'
B被创建了
原型模式配置下报错
-
singleton prototype request session
<bean id="a" class="com.atguigu.interview1024.depend.A" scope="prototype">
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'a': Requested bean is currently in creation: Is there an unresolvable circular reference?
默认的单例(singleton)的场景是支持循环依赖的,不报错
原型(Prototype)的场景是不支持循环依赖的,会报错
- 默认单例,修改为原型scope=“prototype”
3级缓存
重要结论(spring内部通过3级缓存来解决循环依赖)
-
DefaultSingletonBeanRegistry 使用这个类 Default Singleton Bean Registry 默认 单例 bean 注册
只有单例的bean会通过三级缓存提前暴露来解决循环依赖的问题,而非单例的bean,每次从容器中获取都是一个新的对象,都会重新创建,所以非单例的bean是没有缓存的,不会将其放到三级缓存中。
第一级缓存〈也叫单例池)singletonObjects:存放已经经历了完整生命周期的Bean对象
- Spring 容器,就是 Spring工厂,生产的产品(对象)
第二级缓存: earlySingletonObjects,存放早期暴露出来的 Bean对象,Bean的生命周期未结束(属性还未填充完整)
- 放 半成品的
第三级缓存: Map<String, ObjectFactory<?>> singletonFactories,存放可以生成Bean的工厂
- 存放工厂的
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
private static final int SUPPRESSED_EXCEPTIONS_LIMIT = 100;
//线程安全。一级缓存。
private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
//1级缓存,线程安全。
//1级 和 2级,Value 都是 Object
//叫 三级缓存
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
//过早 暴露的,叫:二级缓存
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap(16);
}
源码准备知识
实例化
内存中申请一块内存空间
租赁好房子,自己的家具东西还没有搬家进入
<bean id="a" class="com.atguigu.interview1024.depend.A" scope="session"> //实例化定义
<property name="b" ref="b"></property> //初始化属性定义
</bean>
初始化属性填充
完成属性的各种赋值
装修、家电家具进场
*** 3个Map和四大方法,3个缓存
private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap(16);
getSingleton 获得单例bean,有就拿出来
doCreateBean 没有就用这个方法 创建。
populateBean 填充属性
addSingleton 添加到缓存,从 三级 到 1级,升级。1级后,就能用了。
populate
英
/ˈpɒpjuleɪt/
v.
(大批人或动物)居住于,生活于;充满,出现于(某地方,领域);迁移,殖民于;(给文件)增添数据,输入数据
第一层singletonObjects存放的是已经初始化好了的Bean,
- 单例对象的缓存: bean名称bean实例,即:所谓的单例池。表示已经经历了完整生命周期的 Bean对象
第一级缓存
第二层earlySingletonObjects存放的是实例化了,但是未初始化的Bean,
- 早期的单例对象的高速缓存: bean名称—bean实例。
表示 Bean的生命周期还没走完(Bean的属性还未填充)就把这个Bean存入该缓存中也就是实例化但未初始化的bean放入该缓存里
第二级缓存- 房子 买回来了,还没装修。
第三层singletonFactories存放的是FactoryBean。假如A类实现了FactoryBean,那么依赖注入的时候不是A类,而是A类产生的Bean
- 单例工厂的高速缓存:bean 名称—ObjectFactory o表示存放生成Bean的工厂
第三级缓存</ b>
*** 迁移说明
A/B两对象在三级缓存中的迁移说明
-
A创建过程中需要B,于是A将自己放到三级缓里面,去实例化B
- A先放入 3缓,实例化B
-
B实例化的时候发现需要A,于是B先查一级缓存,没有,再查二级缓仔,还是没有,再查三级缓存,伙到A然后把三级缓存里面的这个A放到二级缓存里面,并删除三级缓存里面的A
- B 实例化 需要A,查询 1 2 3 缓。3缓中 查到 A,A放入 2缓。
- 三级 升 2级,3级会删掉。
-
B顺利初始化完毕,将自己放到一级缓存里面(此时B里面的A依然是创建中状态)
然后回来接着创建A,此时B已经创建结束,直接从一级缓存里面拿到B,然后完成创建,并将A自己放到一级缓存里面。- B 放入 1级缓存。
- A开始创建,直接从 一级缓存中 拿出B 。将 自己放入 一级缓存。
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
//3缓里 如果没有,就从工厂制造
@FunctionalInterface
public interface ObjectFactory<T> {
T getObject() throws BeansException;
}
源码分析
1. 开始断点 ClassPathXmlApplicationContext
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
A a = context.getBean("a", A.class);
B b = context.getBean("b", B.class);
步过 步入 强制步入 跳出
2. 进入构造
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
}
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}
public ClassPathXmlApplicationContext(//refresh 传递的为true
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
3. 断点到:AbstractApplicationContext 核心方法 refresh
- 加载容器 初始化
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
}
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
//配置了2个Bean,会打印:
//Loaded 2 bean definitions from class path resource [applicationContext.xml
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
4. 断点到:AbstractApplicationContext的finishBeanFactoryInitialization
-
依然是 AbstractApplicationContext
-
完成 对象工厂 初始化
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
}
finishBeanFactoryInitialization(beanFactory);
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
5. 断点到DefaultListableBeanFactory的 preInstantiateSingletons()
- 即 上个方法的最后一个 方法
beanFactory.preInstantiateSingletons();
- 进入这里类
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
}
- 方法如下
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Pre-instantiating singletons in " + this);
}
//触发 初始化 所有的 ,但不包括 懒加载的 beans
//list 里面有 两个值,a 和 b
List<String> beanNames = new ArrayList(this.beanDefinitionNames);
Iterator var2 = beanNames.iterator();
while(true) {
String beanName;
Object bean;
do {
while(true) {
RootBeanDefinition bd;
do {
do {
do {
if (!var2.hasNext()) {
var2 = beanNames.iterator();
while(var2.hasNext()) {
beanName = (String)var2.next();
Object singletonInstance = this.getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, this.getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
return;
}
beanName = (String)var2.next();
bd = this.getMergedLocalBeanDefinition(beanName);
} while(bd.isAbstract());
} while(!bd.isSingleton());
} while(bd.isLazyInit());
if (this.isFactoryBean(beanName)) {
bean = this.getBean("&" + beanName);
break;
}
//执行getBean
this.getBean(beanName);
}
} while(!(bean instanceof FactoryBean));
FactoryBean<?> factory = (FactoryBean)bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
SmartFactoryBean var10000 = (SmartFactoryBean)factory;
((SmartFactoryBean)factory).getClass();
isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext());
} else {
isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
}
if (isEagerInit) {
this.getBean(beanName);
}
}
}
6. 断点到DefaultListableBeanFactory的this.getBean(beanName);
this.getBean(beanName);
7. 进入AbstractBeanFactory的getBean()的 doGetBean
- 调用 doGetBean
- 所有 do开头的方法,都是 干实事 的。
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
}
public Object getBean(String name) throws BeansException {
return this.doGetBean(name, (Class)null, (Object[])null, false);
}
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
//看看 没有 配置别名
String beanName = this.transformedBeanName(name);
//重要的代码
Object sharedInstance = this.getSingleton(beanName);
Object bean;
if (sharedInstance != null && args == null) {
if (this.logger.isTraceEnabled()) {
if (this.isSingletonCurrentlyInCreation(beanName)) {
this.logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
} else {
this.logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else {
if (this.isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
BeanFactory parentBeanFactory = this.getParentBeanFactory();
if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
String nameToLookup = this.originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
}
if (args != null) {
return parentBeanFactory.getBean(nameToLookup, args);
}
if (requiredType != null) {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
return parentBeanFactory.getBean(nameToLookup);
}
if (!typeCheckOnly) {
this.markBeanAsCreated(beanName);
}
try {
//在 Spring 源码中 叫:RootBean
RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
this.checkMergedBeanDefinition(mbd, beanName, args);
//是否配置了 dependsOn,依赖加载,没配置
String[] dependsOn = mbd.getDependsOn();
String[] var11;
if (dependsOn != null) {
var11 = dependsOn;
int var12 = dependsOn.length;
for(int var13 = 0; var13 < var12; ++var13) {
String dep = var11[var13];
if (this.isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
this.registerDependentBean(dep, beanName);
try {
this.getBean(dep);
} catch (NoSuchBeanDefinitionException var24) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var24);
}
}
}
//这里是重点,要创建了。
if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
var11 = null;
Object prototypeInstance;
try {
this.beforePrototypeCreation(beanName);
prototypeInstance = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
}
Scope scope = (Scope)this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
this.beforePrototypeCreation(beanName);
Object var4;
try {
var4 = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
return var4;
});
bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException var23) {
throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton", var23);
}
}
} catch (BeansException var26) {
this.cleanupAfterBeanCreationFailure(beanName);
throw var26;
}
}
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = this.getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
} else {
return convertedBean;
}
} catch (TypeMismatchException var25) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", var25);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
} else {
return bean;
}
}
8. *** DefaultSingletonBeanRegistry的 this.getSingleton()四大方法之一
- 三缓最终是一个 lambda表达式,负责建造。
- 建造的 对象,放入 二级缓存。 (二级缓存里 ,叫做 半成品)
- a 依赖 b,创建的时候,a放入了 3级缓存。
- 之后 要b,创建。
- b 依赖 a,取出 a的 值,放入到 2级缓存,并且 清理 3级缓存中的 a。b创建完毕,直接放入1级缓存。
- b 创建,也是先放入3级缓存。最后直接 升入一级缓存。
- a,是 先3级,b把a,放到2级。b初始化完毕,a在升入3级。
- 最后 a得到 依赖 后,a创建 完毕。
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
}
@Nullable
public Object getSingleton(String beanName) {
return this.getSingleton(beanName, true);
}
//允许早起 暴露引用,为 allowEarlyReference
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//从 1级缓存中 获取看看
Object singletonObject = this.singletonObjects.get(beanName);
//a 只是探寻一下,还没有创建
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
//这里 不会走。下次会走
//一级缓存找不到,这里 去 二级缓存中找
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
synchronized(this.singletonObjects) {
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) {
//二级缓存,也找不到 去三级缓存中 找。
//三缓里 lambda表达式,获取会直接调到 这个表达式
//通过 这个表达式,获取到对象
singletonObject = singletonFactory.getObject();
//找到了,放入 二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
//移除3级缓存的 对象。
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
9. doGetBean的 this.getSingleton。核心方法4 addSingleton
//这里是重点,要创建了。
if (mbd.isSingleton()) {//要去这里执行
sharedInstance = this.getSingleton(beanName, () -> {
try {
//从工厂里获取,singletonFactory.getObject();
//到了这里
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized(this.singletonObjects) {
//先去 一级缓存拿
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (this.logger.isDebugEnabled()) {
this.logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
this.beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = this.suppressedExceptions == null;
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet();
}
try {
//从 工厂里 获取 bean。会调用
singletonObject = singletonFactory.getObject();
newSingleton = true;
} catch (IllegalStateException var16) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw var16;
}
} catch (BeanCreationException var17) {
BeanCreationException ex = var17;
if (recordSuppressedExceptions) {
Iterator var8 = this.suppressedExceptions.iterator();
while(var8.hasNext()) {
Exception suppressedException = (Exception)var8.next();
ex.addRelatedCause(suppressedException);
}
}
throw ex;
} finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
this.afterSingletonCreation(beanName);
}
//最后一步,加到容器里
if (newSingleton) {
this.addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
//加入到 一级缓存,清理 2级 ,3级缓存。b是从3级缓存,直接到1级缓存。
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);
}
}
10. AbstractBeanFactory 的 doGetBean的 this.createBean
- 有的话,this.getSingleton 会获取到。没有的话 我重新了 createBean,会去创建。
if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
11. AbstractAutowireCapableBeanFactory的createBean
- 创建 Bean
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
}
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException var9) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var9);
}
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);
}
try {
//核心方法2,来了
beanInstance = this.doCreateBean(beanName, mbdToUse, args);
if (this.logger.isTraceEnabled()) {
this.logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
} catch (ImplicitlyAppearedSingletonException | BeanCreationException var7) {
throw var7;
} catch (Throwable var8) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", var8);
}
}
12. ** AbstractAutowireCapableBeanFactory的doCreateBean() 四大方法之2 和 3
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
}
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
//建立之前,先清除一次
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//这里是 真正的创建
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
synchronized(mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable var17) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
}
mbd.postProcessed = true;
}
}
//这个很重要,判断是不是单例,允许 循环引用吗,默认为 true
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if (earlySingletonExposure) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
}
//重点方法 addSingletonFactory
this.addSingletonFactory(beanName, () -> {
return this.getEarlyBeanReference(beanName, mbd, bean);
});
}
Object exposedObject = bean;
try {
//赋值属性
this.populateBean(beanName, mbd, instanceWrapper);
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);
}
}
12. AbstractAutowireCapableBeanFactory的createBeanInstance()
- 如上 看到,这个方法 生成了一个 instanceWrapper
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
//通过反射 生成
Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
}
13. ** AbstractAutowireCapableBeanFactory的addSingletonFactory() 放入3级缓存
this.addSingletonFactory(beanName, () -> {
//这类 的方法 后面还有用
return this.getEarlyBeanReference(beanName, mbd, bean);
});
- 有这个类实现
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
}
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized(this.singletonObjects) {
//先 看一级缓存,有没有
if (!this.singletonObjects.containsKey(beanName)) {
//一级缓存没有,进入这里
//先 放入三级缓存里面。singletonFactory就是 Lambda对象
this.singletonFactories.put(beanName, singletonFactory);
//现在 二级缓存,没有。
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
//singletonFactory 就是这个
this.addSingletonFactory(beanName, () -> {
return this.getEarlyBeanReference(beanName, mbd, bean);
});
14. doCreateBean的 populateBean 属性填充方法。到第三步了。
- 获取失败,第一步
- 创建
- 填充
- 填充时 ,发现 a,需要 b,又要创建b
- 添加到缓存
try {
this.populateBean(beanName, mbd, instanceWrapper);
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
}
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
} else {
if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
Iterator var4 = this.getBeanPostProcessors().iterator();
while(var4.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var4.next();
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
....
//进入 最后一行
if (pvs != null) {
this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
}
}
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
while(true) {
while(var11.hasNext()) {
PropertyValue pv = (PropertyValue)var11.next();
if (pv.isConverted()) {
deepCopy.add(pv);
} else {
//找到 a 需要引用 b
String propertyName = pv.getName();
Object originalValue = pv.getValue();
if (originalValue == AutowiredPropertyMarker.INSTANCE) {
Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
if (writeMethod == null) {
throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
}
originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
}
}
- 解决B的引用关系
class BeanDefinitionValueResolver {
@Nullable
private Object resolveReference(Object argName, RuntimeBeanReference ref) {
try {
Class<?> beanType = ref.getBeanType();
Object bean;
if (ref.isToParent()) {
BeanFactory parent = this.beanFactory.getParentBeanFactory();
if (parent == null) {
throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName, "Cannot resolve reference to bean " + ref + " in parent factory: no parent factory available");
}
if (beanType != null) {
bean = parent.getBean(beanType);
} else {
bean = parent.getBean(String.valueOf(this.doEvaluate(ref.getBeanName())));
}
} else {
String resolvedName;
if (beanType != null) {
NamedBeanHolder<?> namedBean = this.beanFactory.resolveNamedBean(beanType);
bean = namedBean.getBeanInstance();
resolvedName = namedBean.getBeanName();
} else {
//从工厂里,找 bean b。 和 a 一样 getBean。又是回到了 第一步。获取,获取失败创建
resolvedName = String.valueOf(this.doEvaluate(ref.getBeanName()));
bean = this.beanFactory.getBean(resolvedName);
}
this.beanFactory.registerDependentBean(resolvedName, this.beanName);
}
if (bean instanceof NullBean) {
bean = null;
}
return bean;
} catch (BeansException var7) {
throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName, "Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, var7);
}
}
总结
为什么一定要用3级缓存,我用2级可否?1级可否?
getSingleton 获得单例bean,有就拿出来
doCreateBean 没有就用这个方法 创建。
populateBean 填充属性
addSingleton 添加到缓存,从 三级 到 1级,升级。1级后,就能用了。
3个缓存,4个方法
- getSingleton 能获得,就直接用
- 1级没有去2级,2级没有去3级,
- 3级有了,把3级 移动到 2级。
- doCreateBean 不能获得,就创建
- populateBean 创建后 填充属性
- addSingleton 最后添加到缓存
Spring创建 bean主要分为两个步骤,创建原始bean对象,接着去填充对象属性和初始化
每次创建bean之前,我们都会从缓存中查下有没有该bean,因为是单例,只能有一个
当我们创建beanA的原始对象后,并把它放到三级缓存中,接下来就该填充对象属性了
这时候发现依赖了beanB,接着就又去创建
beanB,同样的流程,创建完beanB填充属性时又发现它依赖了beanA又是同样的流程
不同的是:
这时候可以在三级缓存中查到刚放进去的原始对象 beanA,所以不需要继续创建,用它注入beanB,完成 beanB的创建
既然beanB创建好了,所以 beanA就可以完成填充属性的步骤了,接着执行剩下的逻辑,闭环完成
Spring解决循环依赖依靠的是Bean的"中间态"这个概念,而这个中间态指的是已经实例化但还没初始化的状态……>半成品。实例化的过程汉是通过构造器创建的,如果A还没创建好出来怎么可能提前曝光,所以构造器的循环依赖无法解决。
Spring为了解决单例的循环依赖问题,使用了三级缓存。
其中一级缓存为单例池( singletonObjects
二级缓存为提前曝光对象( earlySingletonObjects)
- 有了 这个A的半成品,所以 B 就可以 引用A
- 等 B 完成了,在 引用这个半成品 A
三级缓存为提前曝光对象工厂( singletonFactories) 。
假设A、B循环引用,实例化A的时候就将其放入三级缓存中,接着填充属性的时候,发现依赖了B,同样的流程也是实例化后放入三级缓存,按着去填充属性时又发现自己依赖A,这时候从缓存中查找到早期暴露的A,没有AOP代理的话,直接将A的原始对象注入B,完成B的初始化后,进行属性填充和初始化,这时候B完成后,就去完成剩下的A的步骤,如果有AOP代理,就进行AOP处理获取代理后的对象A,注入B,走
剩下的流程。
先创建beanA
- getBean(beanA)
- doGetBean(bearA…)
尝试从各级缓存获取bean
- getSingleton(beanA) = = NULL
开始创建bean实例
- getSingleton(beanA.singletonFactory)
- createBean(beanA, mmbd, args)
- doCreateBean(beanA…)
创建bean对象
- createBeanlnstance(beanA,…–)
添加到三级缓存
- addSingletonFactory(beanA,singletonFactory)
- v是 名字,key是 lambda表达式
属性注入
- populateBean(beainA, …)
- 属性 填充时,发现依赖B,接着去找B,走同样的流程
- 创建依赖的beanB,getBean(beanB)
- …
- populateBean(beanB,…)
- beanB获取beanA的早期引用
- getBean(beanA)
- daGetBean(bearA…-.)
- 由于第一步已经添加了缓存,所以这里不为空,并将三级缓存移到二级
- getSingleton(beanA)
- 返回beanA 的原始对象
- beanB获取beanA的早期引用
- initializeBean(beanB,…)
- addSiingleton(beanB,singletonObject)
- 属性 填充时,发现依赖B,接着去找B,走同样的流程
最后完成beanA的实例化
- 初始化bean initializeBean(beanA,…)
- addlSingleton(beanA, singletonObject)
- getObjectForBeanInstance(…)
1调用doGetBean()方法,想要获取beanA,于是调用getSingleton()方法从缓存中查找beanA
2在getSingleton()方法中,从一级缓存中查找,没有,返回null
3 doGetBean()方法中获取到的beanA为null,于是走对应的处理逻辑,调用getSingleton()的重载方法(参数为ObjectFactory的)
4在getSingleton()方法中,先将beanA_name添加到一个集合中,用于标记该beani正在创建中。然后回调匿名内部类的creatBean方法
5进入AbstractAutowireCapableBeanFactory#doCreateBean,先反射调用构造器创建出beanA的实例,然后判断:是否为单例、是否允许提前暴露引用(对于单例一般为true)、是否正在创建中(即是否在第四步的集合中)。判断为true则将beanA添加到【三级缓存】中
6对beanA进行属性填充,此时检测到beanA依赖于beanB,于是开始查找beanB
7调用doGetBean()方法,和上面beanA的过程一样,到缓存中查找beanB,没有则创建,然后给beanB填充属性
8此时beanB依赖于beanA,调用getSingleton()获取beanA,依次从一级、二级、三级缓存中找,此时从三级缓存中获取到beanA的创建工厂,通过创建工厂获取到singletonObject,此时这个singletonObject指向的就是上面在doCreateBean()方法中实例化的beanA
9这样beanB就获取到了beanA的依赖,于是beanB顺利完成实例化,并将beanA从三级缓存移动到二级缓存中
10随后beanA继续他的属性填充工作,此时也获取到了beanB,beanA也随之完成了创建,回到getSingleton()方法中继续向下执行,将beanA从二.级缓存移动到一级缓存中
最核心的 getSingleton
//允许早起 暴露引用,为 allowEarlyReference
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//从 1级缓存中 获取看看
Object singletonObject = this.singletonObjects.get(beanName);
//a 只是探寻一下,还没有创建
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
//这里 不会走。下次会走
//一级缓存找不到,这里 去 二级缓存中找
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
synchronized(this.singletonObjects) {
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) {
//二级缓存,也找不到 去三级缓存中 找。
//三缓里 lambda表达式,获取会直接调到 这个表达式
//通过 这个表达式,获取到对象
singletonObject = singletonFactory.getObject();
//找到了,放入 二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
//移除3级缓存的 对象。
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
最后
以上就是文静路人为你收集整理的【2020尚硅谷Java大厂面试题第三季 03】Spring AOP 5大通知,Spring4和5,6不同,循环依赖,三级缓存源码解析(4大方法,3个Map)的全部内容,希望文章能够帮你解决【2020尚硅谷Java大厂面试题第三季 03】Spring AOP 5大通知,Spring4和5,6不同,循环依赖,三级缓存源码解析(4大方法,3个Map)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复