我是靠谱客的博主 文静路人,最近开发中收集的这篇文章主要介绍【2020尚硅谷Java大厂面试题第三季 03】Spring AOP 5大通知,Spring4和5,6不同,循环依赖,三级缓存源码解析(4大方法,3个Map),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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
  1. @Around 环绕通知之前

    1. @Before 前置通知
    2. 本次运算的结果为:5
  2. @Around 环绕通知之后,对象为:5

  3. @After 后置通知

  4. @AfterReturning 返回后通知

总结:环绕 了 前置和本方法。然后:后置,返回后通知。

  • Before
    • Before + 方法,被 环绕通知 包裹
  • After
  • AfterReturning
异常执行
@Around 环绕通知之前
@Before 前置通知

要调用div方法了

@After 后置通知
@AfterThrowing 异常通知


java.lang.ArithmeticException: / by zero
  1. 环绕前
  2. 前置
  3. 执行方法
  4. 后置
  5. 异常通知

没有 环绕后的逻辑,没有 返回后通知

  • 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两对象在三级缓存中的迁移说明

  1. A创建过程中需要B,于是A将自己放到三级缓里面,去实例化B

    1. A先放入 3缓,实例化B
  2. B实例化的时候发现需要A,于是B先查一级缓存,没有,再查二级缓仔,还是没有,再查三级缓存,伙到A然后把三级缓存里面的这个A放到二级缓存里面,并删除三级缓存里面的A

    1. B 实例化 需要A,查询 1 2 3 缓。3缓中 查到 A,A放入 2缓。
    2. 三级 升 2级,3级会删掉。
  3. B顺利初始化完毕,将自己放到一级缓存里面(此时B里面的A依然是创建中状态)
    然后回来接着创建A,此时B已经创建结束,直接从一级缓存里面拿到B,然后完成创建,并将A自己放到一级缓存里面。

    1. B 放入 1级缓存。
    2. 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 的原始对象
      • initializeBean(beanB,…)
      • addSiingleton(beanB,singletonObject)

最后完成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)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(65)

评论列表共有 0 条评论

立即
投稿
返回
顶部