一、前言
Spring循环依赖
是面试考点之一。面试官可以深挖面试者对 Spring
关于 Bean的生命周期
掌握情况。 Spring循环依赖
也是 Spring
难点之一,逻辑比较绕,需要对 Spring Bean
的生命周期了如指掌。
简单,就是A对象依赖了B对象,B对象依赖了A对象。
@Component public class A { @Autowired B b; } 复制代码
@Component public class B { @Autowired A a; } 复制代码
A 生命周期 1. class文件 2. 通过beanName去缓存中获取对象。一开始,单例池没有,且a也没有处于正在创建集合中,所以不会去二级缓存、三级缓存拿对象,相关代码[标记①] 3. 把对象放到正在创建集合中(beforeSingletonCreation(beanName);) 相关代码[标记②] 4. 通过反射实例化对象(createBeanInstance();) 相关代码[标记③] 5. 添加对象工厂到二级缓存中 相关代码[标记④] 6. 属性填充。在这里发现需要B对象,从单例池获取B->null->且b也没有处于正在创建集合中->实例化B且完成B的生命周期 相关代码[标记⑤] wait for b init... 7. 初始化 相关代码[标记⑥] 8. 从二级缓存中获取Bean 相关代码[标记⑦] 9. 添加到单例池 相关代码[标记⑥] B 生命周期 1. class文件 2. 通过beanName去缓存中获取对象。一开始,单例池没有,且a也没有处于正在创建集合中,所以不会去二级缓存、三级缓存拿 3. 把对象放到正在创建集合中(beforeSingletonCreation(beanName);) (singletonObject = singletonFactory.getObject();) 4. 通过反射实例化对象(createBeanInstance();) 5. 添加对象工厂到二级缓存中 6. 属性填充。在这里发现需要A对象,从单例池获取A->null->此时a在正在创建集合中->从三级缓存中获取对象(如果a存在切面,则返回代理对象),将对象放至二级缓存,删除三级缓存 7. 初始化 8. 从二级缓存中获取Bean 9. 添加到单例池 复制代码
singletonObjects
。存储已走完 Spring
生命周期的 Bean
。注意, 对象
和 Bean
在Spring的世界是完全两个概念。通过反射实例化的叫对象,此时这个对象并未完成 Spring
的生命周期流程(如后置处理器等), Bean
则表示已经完成 Spring
整个生命周期流程。 earlySingletonObjects
。存储已实例化(通过反射创建的对象)但是未走完 Spring
生命周期流程的对象。 singletonFactories
。存储 对象工厂
。目的是在适当的时候通过对象工厂生成 AOP
代理对象。 AOP
代理。对象工厂清楚如何创建对象的AOP代理,但是不会立马创建,而是到合适的时机进行 AOP
代理对象的创建。 二级缓存存
在的目的之一是保证对象只有一次 AOP
代理。当调用三级缓存的 getObject()
方法返回的对象会存入二级缓存,这样,当接下来的依赖者调用的时候, 会先判断 二级缓存
是否有目标对象,如果存在直接返回。 // DefaultSingletonBeanRegistry#getSingleton @Nullable protected Object getSingleton(String beanName, boolean allowEarlyReference) { // 从一级缓存中获取bean,即单例池 Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { // 从二级缓存中获取对象 singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { // 从三级缓存获取对象工厂 ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } return singletonObject; } 复制代码
// DefaultSingletonBeanRegistry#beforeSingletonCreation protected void beforeSingletonCreation(String beanName) { // 1.inCreationCheckExclusions: 判断当前对象是否存在 [被剔除] 集合对象中 注解 excludeFilters=xx // 2.singletonsCurrentlyInCreation: 将当前对象添加 [正在创建单例Bean] 集合中 if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } } 复制代码
// AbstractAutowireCapableBeanFactory#createBeanInstance protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { // 如果为自动装配,则推断出来各种候选的构造方法 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { // 利用推断出来的修行构造方法去实例化对象。如果使用构造器注入,这里直接返回 return autowireConstructor(beanName, mbd, ctors, args); } ctors = mbd.getPreferredConstructors(); if (ctors != null) { // 利用推断出来的候选构造方法去实例化对象 return autowireConstructor(beanName, mbd, ctors, null); } // No special handling: simply use no-arg constructor. // 如果没有推断出合适的构造方法(或者没有提供特殊的构造方法),则使用默认的构造方法 return instantiateBean(beanName, mbd); } 复制代码
// DefaultSingletonBeanRegistry#addSingletonFactory protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(singletonFactory, "Singleton factory must not be null"); synchronized (this.singletonObjects) { if (!this.singletonObjects.containsKey(beanName)) { this.singletonFactories.put(beanName, singletonFactory); this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } } } 复制代码
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { if (hasInstAwareBpps) { if (pvs == null) { pvs = mbd.getPropertyValues(); } // 这里会有三个后置处理器,分别是: // 1、ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor // 2、AutowiredAnnotationBeanPostProcessor // 3、CommonAnnotationBeanPostProcessor // AutowiredAnnotationBeanPostProcessor: 解析@Autowire属性注入 for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { // 属性自动注入主要使用 AutowiredAnnotationBeanPostProcessor后置处理器 PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { return; } } pvs = pvsToUse; } } } 复制代码
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { // 4-1、执行Aware (BeanNameAware、BeanClassLoaderAware 、BeanFactoryAware) invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { // 4.2 初始化前 // △△ 执行Bean后置处理器(lifeCycle Callback) // 重写这个方法[postProcessBeforeInitialization]则会在这里被调用 // lifeCycle callback init by annotation wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { // 4.3、初始化 [InitializingBean] // lifeCycle callback init by interface. invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { // 4.4、初始化后 // 完成AOP,生成动态代理; 事件发布; 监听 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; } 复制代码
// AbstractAutowireCapableBeanFactory#doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) if (earlySingletonExposure) { // 在解决循环依赖时,获取beanName从二级缓存中获取 Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } ... } } ... 复制代码
// DefaultSingletonBeanRegistry#getSingleton public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { // 把当前对象放到 [正在创建] 的集合(singletonsCurrentlyInCreation)当中 beforeSingletonCreation(beanName); // getObject方法会调用AbstractAutowireCapableBeanFactory的createBean方法 singletonObject = singletonFactory.getObject(); //添加到单例池 addSingleton(beanName, singletonObject); } } 复制代码
依赖注入方式 | 循环依赖能否被解决 |
---|---|
均采用setter方法注入 | 能 |
均采用构造器注入 | 不能 |
A中注入B的方式为setter方法,B中注入A的方式为构造器 | 能 |
A中注入B的方式为构造器,B中注入A的方式为setter方法 | 不能 |
注: A
先创建。
小结:
构造函数
的方法注入所依赖的Bean对象(简称B),而B不受限制,可以使用任意方式注入( setter、@Autowire、构造函数)
。 构造函数
注入的原因是在 AbstractAutowireCapableBeanFactory#createBeanInstance
方法中做类型推断时,如果推断是以构造方法实例B,则会直接调用``AbstractAutowireCapableBeanFactory#autowireConstructor ,该方法会通过调用
AbstractAutowireCapableBeanFactory#doCreateBean 创建对象,但是由于A对象没有提前暴露工厂(不给机会呀),所以只能一步步创建,但是走到代码
DefaultSingletonBeanRegistry#getSingleton 的
beforeSingletonCreation 方法时,由于此时A正在创建集合,强行添加则会返回
false`,则抛出异常。相关代码③ 如果解决循环依赖呢?
setter