首先,我们在3.1 spring5源码系列--循环依赖 之 手写代码模拟spring循环依赖 中手写了循环依赖的实现. 这个实现就是模拟的spring的循环依赖. 目的是为了更容易理解spring源码.
下面我们就进入正题,看看spring的循环依赖源码.
一、getBean整体流程
目标很明确了,就是要看看spring如何解决循环依赖的.
代码入口是refresh()#finishbeanfactoryInitialization(beanfactory);
二、拆解研究流程中的每一步
调用方法beanfactory.preInstantiateSingletons();实例化剩余的单例bean. 为什么是剩余的?很显然我们在上面已经实例化一部分了.比如配置类,postProcessor等.
2.1 入口
- 1 @Override
- 2 public void preInstantiateSingletons() throws BeansException {
- 3 if (logger.isTraceEnabled()) {
- 4 logger.trace("Pre-instantiating singletons in " + this);
- 5 }
- 6
- 7
- 8 // 获取容器中所有bean定义的名字
- 9 List<String> beanNames = new ArrayList<>(.beanDefinitionNames);
- 10
- 11 Trigger initialization of all non-lazy singleton beans...
- 12 /**
- 13 * 第一步: 循环bean定义的name
- 14 */
- 15 for (String beanName : beanNames) {
- 16 获取bean定义
- 17 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
- 18 生产bean定义的条件: 不是抽象的,是单例的,不是懒加载的. 符合这个标准的,最后才会调用getBean()生产bean
- 19 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
- 20 这里判断是不是工厂bean,这里和beanfactory不是一个意思,判断当前这个bean是否实现了beanfactory的接口
- 21 (isfactorybean(beanName)) {
- 22 Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
- 23 (bean instanceof factorybean) {
- 24 final factorybean<?> factory = (factorybean<?>) bean;
- 25 boolean isEagerInit;
- 26 if (System.getSecurityManager() != null && factory instanceof Smartfactorybean) {
- 27 isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
- 28 ((Smartfactorybean<?>) factory)::isEagerInit,29 getAccessControlContext());
- 30 }
- 31 else {
- 32 isEagerInit = (factory instanceof Smartfactorybean &&
- 33 ((Smartfactorybean<?>) factory).isEagerInit());
- 3435 (isEagerInit) {
- 36 获取bean
- 37 getBean(beanName);
- 3839 }
- 40 }
- 41 {
- // 第二步: 调用bean定义
- 42 getBean(beanName);
- 4344 }
- 45 }
- 46
- 47 Trigger post-initialization callback for all applicable beans...
- 48
- 51 52 从缓存中得到实例instance
- 53 Object singletonInstance = getSingleton(beanName);
- 54 (singletonInstance instanceof SmartInitializingSingleton) {
- 55 final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
- 56 null) {
- 57 AccessController.doPrivileged((PrivilegedAction<Object>) () ->58 smartSingleton.afterSingletonsInstantiated();
- 59 return ;
- 60 },getAccessControlContext());
- 6162 63 smartSingleton.afterSingletonsInstantiated();
- 64656667 }
首先,循环bean定义,这和我们模拟spring循环的第一步是一样的.
第二步: 判断从BeanDefinitionMap中取出来的这个bean是否满足生产bean的条件
我们注意代码注释中, 生产bean定义的条件: 不是抽象的,最后才会调用getBean()生产bean
然后:调用getBean()
到目前为止,我们完成了上图源码图的第一部分:
2.2 创建bean前的准备工作
接下来看看getBean().doGetBean()方法
- 1 protected <T> T doGetBean(final String name,@Nullable final Class<T> requiredType,1)">2 @Nullable final Object[] args,boolean typeCheckOnly) throws BeansException {
- 3
- 4 // 第一步: 转换bean name. 在这里传入进来的name可能是别名,也有可能是工厂bean的name,所以在这里进行一个转换
- 5 final String beanName = transformedBeanName(name);
- 6 Object bean;
- 7
- Eagerly check singleton cache for manually registered singletons.
- 9 // 第二步: 尝试去缓存中获取对象,如果没有获取到就创建bean
- 10 Object sharedInstance = getSingleton(beanName);
- if (sharedInstance != null && args == ) {
- 12 13 判断当前类是否是正在创建中
- 14 (isSingletonCurrentlyInCreation(beanName)) {
- 15 logger.trace(Returning eagerly cached instance of singleton bean '" + beanName +
- 16 ' that is not fully initialized yet - a consequence of a circular reference"17 }
- 18 {
- 19 logger.trace(Returning cached instance of singleton bean '" + beanName + '2021 }
- 22 bean = getObjectForBeanInstance(sharedInstance,name,beanName,2324
- 25 26 Fail if we're already creating this bean instance:
- 27 We're assumably within a circular reference.
- 28 *
- 29 * 判断当前的bean是不是多例,如果是这抛出异常
- 30 *
- 31 * 判断当前这个bean是不是多例bean. 如果配置了@Scope("prototype") 就表示这是一个多例的bean
- 32 * spring 只能解决单例对象的setter注入的循环依赖,不能解决构造器注入
- 33 *
- 34 * 如果是多例的bean,当前正在创建bean,也会抛出异常---这也是循环依赖的问题
- 35 */
- 36 (isPrototypeCurrentlyInCreation(beanName)) {
- 37 throw new BeanCurrentlyInCreationException(beanName);
- 39
- 40 *
- 41 * 下面这段代码是关于子父容器的,只有spring mvc继承自spring,才会有子父容器的问题.
- 42 43 Check if bean definition exists in this factory.
- 44 beanfactory parentbeanfactory = getParentbeanfactory();
- 45 if (parentbeanfactory != null && !containsBeanDefinition(beanName)) {
- 46 Not found -> check parent.
- 47 String nameToLookup = originalBeanName(name);
- 48 (parentbeanfactory instanceof Abstractbeanfactory) {
- 49 return ((Abstractbeanfactory) parentbeanfactory).doGetBean(
- 50 nameToLookup,requiredType,args,typeCheckOnly);
- 5152 else if (args != 53 Delegation to parent with explicit args.
- 54 (T) parentbeanfactory.getBean(nameToLookup,args);
- 55if (requiredType != 57 No args -> delegate to standard getBean method.
- 58 parentbeanfactory.getBean(nameToLookup,requiredType);
- 5960 61 (T) parentbeanfactory.getBean(nameToLookup);
- 6264
- 65 *
- 66 * 方法参数typeCheckOnly是用来判断#getBean()方法时,表示是否为仅仅进行类型检查,67 * 如果不仅仅做类型检查,而是创建bean对象,则需要调用#markBeanAsCreated(String name)
- 68 *
- 69 70 if (!typeCheckOnly) {
- 71 markBeanAsCreated(beanName);
- 7273
- 74 try75 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
- 76 checkMergedBeanDefinition(mbd,1)">77
- 78 Guarantee initialization of beans that the current bean depends on.
- 79 *
- 80 * 现在有两个bean1,bean2,加载的时候调用的是bean1,bean2. 但如果我们想要bean2优先加载,就使用@DependOn注解
- 81 * 用来解析带有dependOn注解的类
- 82 83 String[] dependsOn = mbd.getDependsOn();
- 84 if (dependsOn != 85 (String dep : dependsOn) {
- 86 (isDependent(beanName,dep)) {
- 87 BeanCreationException(mbd.getResourceDescription(),1)">88 Circular depends-on relationship between '' and '" + dep + 89 }
- 90 registerDependentBean(dep,beanName);
- 91 92 getBean(dep);
- 9394 catch (NoSuchBeanDefinitionException ex) {
- 95 96 ' depends on missing bean ',ex);
- 9798 }
- 99100
- 101 Create bean instance.
- 102 *
- 103 * 第三步: 创建单例bean实例
- 104 105 if (mbd.isSingleton()) { 处理单例bean
- 106 *
- 107 * 这里getSingleton()和上面的getSigleton不一样,上面的是从一级缓存中拿.
- 108 * 这个getSingleton()就办了一件事: 将bean设置为正在创建的状态. 这个状态很重要,如果出现循环依赖,发现bean正在创建,就不会再创建了
- 109 110 sharedInstance = getSingleton(beanName,() ->111 112 createBean(beanName,mbd,args);
- 113114 (BeansException ex) {
- 115 Explicitly remove instance from singleton cache: It might have been put there
- 116 eagerly by the creation process,to allow for circular reference resolution.
- 117 Also remove any beans that received a temporary reference to the bean.
- 118 destroySingleton(beanName);
- 119 throw ex;
- 120121 });
- 122 得到bean实例对象
- 123 bean = getObjectForBeanInstance(sharedInstance,mbd);
- 124125
- 126 if (mbd.isPrototype()) { 处理多例bean
- 127 It's a prototype -> create a new instance.
- 128 Object prototypeInstance = 129 130 当前正在创建多例bean
- 131 beforePrototypeCreation(beanName);
- 132 执行创建bean
- 133 prototypeInstance =134135 finally136 afterPrototypeCreation(beanName);
- 137138 获取bean实例对象
- 139 bean = getObjectForBeanInstance(prototypeInstance,1)">140141
- 142 else { 处理其他类型的bean
- 143 String scopeName = mbd.getScope();
- 144 final Scope scope = this.scopes.get(scopeName);
- 145 if (scope == 146 new IllegalStateException(No Scope registered for scope name '" + scopeName + );
- 147148 149 Object scopedInstance = scope.get(beanName,1)">150 beforePrototypeCreation(beanName);
- 151 152 153 }
- 154 155 afterPrototypeCreation(beanName);
- 156157 });
- 158 bean = getObjectForBeanInstance(scopedInstance,1)">159160 (IllegalStateException ex) {
- 161 BeanCreationException(beanName,1)">162 Scope '' is not active for the current thread; consider " +
- 163 defining a scoped proxy for this bean if you intend to refer to it from a singleton164 ex);
- 165166167168 169 cleanupAfterBeanCreationFailure(beanName);
- 170 171172 }
在这里,首先从缓存中获取bean,看缓存中是否已经存在了
- Object sharedInstance = getSingleton(beanName);
然后,如果缓存中已经存在了,那么久直接取出来. 代码如下:
- if (sharedInstance != null && args == null) {
- (logger.isTraceEnabled()) {
- 判断当前bean是否是正在创建中(单例bean)
- (isSingletonCurrentlyInCreation(beanName)) {
- logger.trace(" + beanName +
- );
- }
- {
- logger.trace();
- }
- }
- bean = getObjectForBeanInstance(sharedInstance,null);
- }
如果是空,就说明是第一次创建,执行else的部分
首先,判断是否是正在创建的多例bean,如果是正在创建的多例bean,就抛出异常,
已经是正在创建了,说明这至少是第二次了,这里处理的是单例bean的循环依赖,不处理多例bean的循环依赖,所以抛出异常
对应的代码是这一句
- *
- 29 * 判断当前的bean是不是多例,如果是这抛出异常
- 30 *
- 31 * 判断当前这个bean是不是多例bean. 如果配置了@Scope("prototype") 就表示这是一个多例的bean
- 32 * spring 只能解决单例对象的setter注入的循环依赖,1)">38 }
那么,接下来就是首次创建bean. 首次创建的bean有三种情况:
第一种,这个bean是单例的.
第二种,这个bean是多例的.
第三种. 其他类型
对应的代码就是这一块. 有行号,可以和上面一一对应上
- if (mbd.isSingleton()) { 处理单例bean
- mbd.isPrototype()) { 处理多例bean
- else { 处理其他类型的bean
- 166 }
我们的重点研究对象是单例bean. 所以,重点看单例bean的实现
- if (mbd.isSingleton()) { // 处理单例bean
- 110 sharedInstance = getSingleton(beanName,() -> {
- 111 try {
- 112 return createBean(beanName,args);
- 113 }
- 114 catch (BeansException ex) {
- 115 // Explicitly remove instance from singleton cache: It might have been put there
- 116 // eagerly by the creation process,to allow for circular reference resolution.
- 117 // Also remove any beans that received a temporary reference to the bean.
- 118 destroySingleton(beanName);
- 119 throw ex;
- 120 }
- });
- 123 bean =124 }
这里的重点是调用了getSingleton(beanName,FactoryObject); FactoryObject是一个接口. 定义了一个钩子方法getObject().
这个接口在这里这是进行了定义,并不会执行. 什么时候执行呢? 后面调用的时候执行.
下面来看看getSingleton()方法,钩子方法也是在这里被调用的.
- public Object getSingleton(String beanName,ObjectFactory<?> singletonFactory) {
- 2 Assert.notNull(beanName,Bean name must not be null3 synchronized (.singletonObjects) {
- 4 // 第一步: 从一级缓存中获取单例对象
- 5 Object singletonObject = this.singletonObjects.(beanName);
- 6 if (singletonObject == 7 .singletonsCurrentlyInDestruction) {
- 8 BeanCreationNotAllowedException(beanName,1)">9 Singleton bean creation not allowed while singletons of this factory are in destruction 10 (Do not request a bean from a beanfactory in a destroy method implementation!)1112 (logger.isDebugEnabled()) {
- 13 logger.debug(Creating shared instance of singleton bean '1415 // 第二步: 将bean添加到singletonsCurrentlyInCreation中,表示bean正在创建
- 16 beforeSingletonCreation(beanName);
- 17 boolean newSingleton = false18 boolean recordSuppressedExceptions = (this.suppressedExceptions == 19 (recordSuppressedExceptions) {
- 20 this.suppressedExceptions = new LinkedHashSet<>();
- 22 23 // 第三步: 这里调用getObject()钩子方法,就会回调匿名函数,调用singletonFactory的createBean()
- 24 singletonObject = singletonFactory.getObject();
- 25 newSingleton = true2627 28 Has the singleton object implicitly appeared in the meantime ->
- 29 if yes,proceed with it since the exception indicates that state.
- 30 singletonObject = (beanName);
- 31 32 3335 (BeanCreationException ex) {
- 36 37 for (Exception suppressedException : .suppressedExceptions) {
- ex.addRelatedCause(suppressedException);
- 41 43 44 45 4647 afterSingletonCreation(beanName);
- 4849 (newSingleton) {
- addSingleton(beanName,singletonObject);
- 5253 singletonObject;
- 5455 }
这里是调用getBean().
第一步: 去一级缓存中取成熟的单例bean. 如果拿到了,就直接返回. 如果没拿到. 那么执行创建.
第二步: 在创建之前,先把这个bean放入到正在创建的单例bean集合中. 标记这个bean正在创建中
第三步: 就是调用钩子方法getObject()了. 这个方法的方法体是在上面定义的. 其内容是去创建实例
- sharedInstance = getSingleton(beanName,1)"> {
- {
- // 这里定义了一个钩子函数. 此时只是定义,并不执行. 在真正需要创建bean的地方才会执行
- return createBean(beanName,args);
- }
- (BeansException ex) {
- Explicitly remove instance from singleton cache: It might have been put there
- Also remove any beans that received a temporary reference to the bean.
- destroySingleton(beanName);
- ex;
- }
- });
这里的代码逻辑是完成了创建之前的逻辑
2.3 创建bean
下面看看创建bean的过程
- 1 protected Object doCreateBean(final String beanName,final RootBeanDefinition mbd,final @Nullable Object[] args)
- 2 throws BeanCreationException {
- 3
- 4 Instantiate the bean.
- 5 BeanWrapper instanceWrapper = ;
- 6 (mbd.isSingleton()) {
- 7 instanceWrapper = .factorybeanInstanceCache.remove(beanName);
- 8 }
- 9 if (instanceWrapper == ) {
- 10 *
- 11 * 第一步: 实例化
- 12 * 这里面的调用链非常深,后面再看
- 13 * bean实例化有两种方式
- 14 * 1. 使用反射: 使用反射也有两种方式, 15 * a. 通过无参构造函数 (默认的方式)
- 16 * 从beanDefinition中可以得到beanClass,1)"> 17 * ClassName = BeanDefinition.beanClass
- 18 * Class clazz = Class.forName(ClassName);
- 19 * clazz.newInstance();
- 20 * 这样就可以实例化bean了
- 21 *
- 22 * b. 通过有参函数.
- 23 * ClassName = BeanDefinition.beanClass
- 24 25 * Constractor con = class.getConstractor(args....)
- 26 * con.newInstance();
- 27 28 * 2. 使用工厂
- 29 * 我们使用@Bean的方式,就是使用的工厂模式,自己控制实例化过程
- 30 31 */
- 32 instanceWrapper = createBeanInstance(beanName,args);
- 33 34 这里使用了装饰器的设计模式
- 35 final Object bean = instanceWrapper.getWrappedInstance();
- 36 Class<?> beanType = instanceWrapper.getWrappedClass();
- 37 if (beanType != NullBean.class 38 mbd.resolvedTargetType = beanType;
- 39 40
- 41 Allow post-processors to modify the merged bean definition.
- 42 允许后置处理器修改已经合并的beanDefinition
- 43 synchronized (mbd.postProcessingLock) {
- 44 mbd.postProcessed) {
- 45 {
- 46 applyMergedBeanDefinitionPostProcessors(mbd,beanType,beanName);
- 47 }
- 48 (Throwable ex) {
- 49 50 Post-processing of merged bean definition Failed 51 52 mbd.postProcessed = 53 }
- 54 55
- 56 57 * 缓存单例bean到三级缓存中,以防止循环依赖
- 58 * 判断是否是早期引用的bean,如果是,则允许提前暴露引用
- 59 *
- 60 * 判断是否能够早起暴露的条件
- 61 * 1. 是单例
- 62 * 2. 允许循环依赖
- 63 * 3. 正在创建的bean
- 64 65 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
- 66 isSingletonCurrentlyInCreation(beanName));
- 67 (earlySingletonExposure) {
- 68 (logger.isTraceEnabled()) {
- 69 logger.trace(Eagerly caching bean '" + beanName +
- 70 ' to allow for resolving potential circular references);
- 71 72 把我们的早期对象包装成一个singletonFactory对象,该对象提供了getObject()方法,把静态的bean放到三级缓存中去了.
- 73 addSingletonFactory(beanName,1)"> getEarlyBeanReference(beanName,bean));
- 74 75
- 76 Initialize the bean instance.
- 77 Object exposedObject = bean;
- 78 79 第二步:填充属性,给属性赋值(调用set方法) 这里也是调用的后置处理器
- 80 populateBean(beanName,instanceWrapper);
- 81 // 第三步: 初始化.
- 82 exposedObject = initializeBean(beanName,exposedObject,mbd);
- 83 84 85 if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
- 86 (BeanCreationException) ex;
- 87 88 89 BeanCreationException(
- 90 mbd.getResourceDescription(),1)">Initialization of bean Failed 91 92 93
- 94 95 * 初始化完成以后,判断是否是早期的对象
- 96 * 是循环依赖. 才会走进这里来
- 97 98 99 去缓存中获取到我们的对象 由于传递的allowEarlyReference是false,要求只能在一级二级缓存中取
- 100 正常的普通的bean(不存在循环依赖的bean) 创建的过程中,不会把三级缓存提升到二级缓存中.
- 101 Object earlySingletonReference = getSingleton(beanName,1)">102 if (earlySingletonReference != 103 if (exposedObject == bean) {
- 104 exposedObject = earlySingletonReference;
- 105 106 this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
- 107 String[] dependentBeans = getDependentBeans(beanName);
- 108 Set<String> actualDependentBeans = (dependentBeans.length);
- 109 (String dependentBean : dependentBeans) {
- 110 removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
- 111 actualDependentBeans.add(dependentBean);
- 112 }
- 113 }
- 114 actualDependentBeans.isEmpty()) {
- 115 BeanCurrentlyInCreationException(beanName,1)">116 Bean with name '' has been injected into other beans [" +
- 117 StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
- 118 ] in its raw version as part of a circular reference,but has eventually been 119 wrapped. This means that said other beans do not use the final version of the 120 bean. This is often the result of over-eager type matching - consider using 121 'getBeanNamesForType' with the 'allowEagerInit' flag turned off,for example.122 123 124 125 126
- 127 Register bean as disposable.
- 128 129 registerDisposableBeanIfNecessary(beanName,bean,1)">130 131 (BeanDefinitionValidationException ex) {
- 132 133 mbd.getResourceDescription(),1)">Invalid destruction signature134 135
- 136 exposedObject;
- 137 }
首先,实例化bean,实例化的方式有两种. 一种是通过反射,另一种是通过动态
- 1 2 3 4 5 * 1. 使用反射: 使用反射也有两种方式,1)"> 6 7 8 9 10 11 12 13 14 15 16 17 18 19 * 2. 使用工厂
- 20 21 22 23 instanceWrapper = createBeanInstance(beanName,args);
判断是否是早期暴露的bean. 满足早期暴露的bean的三个条件是
1. 是单例的
2. 允许循环依赖
3. bean已经是处在正在创建中的行列了.
- 判断是否能够早起暴露的条件
- * 1. 是单例
- * 2. 允许循环依赖
- * 3. 正在创建的bean
- */
- boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
- isSingletonCurrentlyInCreation(beanName));
创建bean的第二步: 属性赋值
在这里会判断,是否带有@Autowired的属性. 分为两种一种是Name,一种是Type
- @SuppressWarnings(deprecation") for postProcessPropertyValues
- protected populateBean(String beanName,RootBeanDefinition mbd,@Nullable BeanWrapper bw) {
- if (bw == ) {
- (mbd.hasPropertyValues()) {
- BeanCreationException(
- mbd.getResourceDescription(),1)">Cannot apply property values to null instance);
- }
- {
- Skip property population phase for null instance.
- ;
- }
- }
- Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
- state of the bean before properties are set. This can be used,for example,1)"> to support styles of field injection.
- if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
- (BeanPostProcessor bp : getBeanPostProcessors()) {
- (bp instanceof InstantiationAwareBeanPostProcessor) {
- InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
- ibp.postProcessAfterInstantiation(bw.getWrappedInstance(),beanName)) {
- ;
- }
- }
- }
- }
- PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : );
- 判断属性是否有Autowired注解
- int resolvedAutowireMode = mbd.getResolvedAutowireMode();
- Autowired是根据名字或者根据类型
- if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
- MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
- // Add property values based on autowire by name if applicable.
- if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
- autowireByName(beanName,bw,newPvs);
- }
- // Add property values based on autowire by type if applicable.
- if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
- autowireByType(beanName,newPvs);
- }
- pvs = newPvs;
- }
- ......
- }
如果按照名字注入
- 1 autowireByName(
- String beanName,AbstractBeanDefinition mbd,BeanWrapper bw,MutablePropertyValues pvs) {
- 3
- 4 String[] propertyNames = unsatisfiedNonSimpleProperties(mbd,bw);
- 5 (String propertyName : propertyNames) {
- 6 (containsBean(propertyName)) {
- 7 // 调用getBean
- 8 Object bean = getBean(propertyName);
- pvs.add(propertyName,bean);
- registerDependentBean(propertyName,1)">11 12 logger.trace(Added autowiring by name from bean name '13 ' via property '" + propertyName + ' to bean named '17 18 logger.trace(Not autowiring property '' of bean '19 ' by name: no matching bean found22 23 }
会再次调用getBean方法. 构建bean. 这是就有可能出现循环依赖了.
按类型注入也是一样的.
只是解析bean的方式不同.
创建bean的第三步: 初始化
- // 第三步: 初始化.
- exposedObject = initializeBean(beanName,mbd);
在初始化bean的时候,会调用很多的aware. 还会调用init-method方法. 以及bean的后置处理器.
第四步:删除实例化和静态方法在缓存中的数据
- *
- * 初始化完成以后,判断是否是早期的对象
- * 是循环依赖. 才会走进这里来
- */
- (earlySingletonExposure) {
- Object earlySingletonReference = getSingleton(beanName,1)">);
- ) {
- bean) {
- exposedObject = earlySingletonReference;
- }
- hasDependentBean(beanName)) {
- String[] dependentBeans = getDependentBeans(beanName);
- Set<String> actualDependentBeans = (dependentBeans.length);
- (String dependentBean : dependentBeans) {
- removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
- actualDependentBeans.add(dependentBean);
- }
- }
- actualDependentBeans.isEmpty()) {
- " +
- StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
- " +
- );
- }
- }
- }
- }
这既是getBean()整个的过程. 中间还有很多细节,没有往里面深入的看,因为spring代码非常的深,看的太深就忘了我们的目标了. 结合之前手写的spring循环依赖的思想看,还是可以看得懂的.
三. 接下来有几个问题
问题1: 为什么需要二级缓存和三级缓存?
一级缓存: 用来存储完整的bean
二级缓存: 用来存储早期的,纯净的bean,也就是没有注入属性的bean
三级缓存: 存的是函数的接口,主要目的是为了解耦
二级缓存 和三级缓存 结合起来,解决了循环依赖下的AOP动态代理的问题
问题2:有没有解决构造函数的循环依赖
答案是没有. 因为构造函数是在实例化的时候构建的. 这个时候bean都还没有创建,所以没有办法处理循环依赖.如果出现构造函数的循环依赖,是会直接报错的..
问题3:有没有解决多例下的循环依赖
也是没有的,因为我们会判断,如果是多例,那么会抛出异常
- 1 /**
- 2 * 第二步: 判断当前bean是否是正在创建中的多例bean,如果是就抛出异常
- 3 *
- 4 * 2. 判断当前这个bean是不是多例bean. 如果配置了@Scope("prototype") 就表示这是一个多例的bean
- 5 * spring 只能解决单例对象的setter注入的循环依赖,不能解决构造器注入
- 6 *
- 7 * 如果是多例的bean,也会抛出异常---这也是循环依赖的问题
- 8 */
- 9 (isPrototypeCurrentlyInCreation(beanName)) {
- 10 BeanCurrentlyInCreationException(beanName);
- 11 }