代码块10.3
代码块12 protected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, RootBeanDefinition mbd) { // 1.如果名称是个factorybean前缀(&)开头的但是却不是FactoryBean,则抛出异常 // (当bean名称前缀是“&”的时候,代表这玩意是个FactoryBean的实例) if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) { throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass()); } // 2.if的前半个条件意思是如果不是FactoryBean,则直接返回beanInstance // 后半个条件是当是个FactoryBean的时候,并且用&开头,则返回beanInstance // (以“&”为前缀代表想获取的是FactoryBean本身,而不是它getObject返回的) if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) { return beanInstance; } // 3.当代码走到这里的时候,beanInstance一定是一个FactoryBean // 并且想要返回的是FactoryBean中getObject所返回的,object即为返回的结果 Object object = null; if (mbd == null) { //4. 尝试从factoryBeanObjectCache(factoryBean创建的对象的缓存)里拿 object = getCachedObjectForFactoryBean(beanName); } // 如果从factoryBean创建的对象的缓存没拿到,就走这个if if (object == null) { //5. 因为一定是FactoryBean,所以可以直接强转 FactoryBean<?> factory = (FactoryBean<?>) beanInstance; //6. 如果mbd为空,并且beanDefinitionMap中包含着这个bean,则去根据这个获取RootBeanDefinition if (mbd == null && containsBeanDefinition(beanName)) { // 7. 获取beanName对应的RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); } //8. 判断Beaneifinition是不是合成的(多次debug这里都是false) boolean synthetic = (mbd != null && mbd.isSynthetic()); object = getObjectFromFactoryBean(factory, beanName, !synthetic); } return object; }
第1处的注释写的很清楚,我们来看看它调用的方法:
代码块13 public static boolean isFactoryDereference(String name) { // BeanFactory.FACTORY_BEAN_PREFIX 值是“&” return (name != null && name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)); }
是不是很简单?其实源码中很多地方也没那么难的😊,第2处也很简单了,我们来看看第4处调用的方法的代码:
代码块14 // 下面方法调用的cache private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<String, Object>(16); protected Object getCachedObjectForFactoryBean(String beanName) { // factoryBeanObjectCache就是factoryBean创建的对象的缓存 Object object = this.factoryBeanObjectCache.get(beanName); return (object != NULL_OBJECT ? object : null); }
这个也是个很简单的方法,我们继续看代码块12中的第6处的这个if条件里调用的方法:
代码块15 @Override public boolean containsBeanDefinition(String beanName) { Assert.notNull(beanName, "Bean name must not be null"); return this.beanDefinitionMap.containsKey(beanName); }
这个beanDefinitionMap就是我们之前讲注册beanDefinition时候的那个map,我们再继续看代码块12中的第8处代码,注意我把第7处的跳过了哈,因为现在不是讲这个第7处方法调用的代码的最好时候,你现在先去根据注释理解,等该讲的时候,我会让你一下子明白的。
代码块16 protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) { // FactoryBean实例是单例 && FactoryBean实例已经存在单例缓存this.singletonObjects中 if (factory.isSingleton() && containsSingleton(beanName)) { // getSingletonMutex()返回的是单例缓存this.singletonObjects synchronized (getSingletonMutex()) { Object object = this.factoryBeanObjectCache.get(beanName); if (object == null) { // 1. 使用factoryBean创建bean object = doGetObjectFromFactoryBean(factory, beanName); // 如果缓存中已经存在,则用缓存中的替换上面生成的 Object alreadyThere = this.factoryBeanObjectCache.get(beanName); if (alreadyThere != null) { object = alreadyThere; }else { // 2. 既然object已经生成了,则执行所有BeanPostProcessor的 // postProcessAfterInitialization方法 if (object != null && shouldPostProcess) { try { object = postProcessObjectFromFactoryBean(object, beanName); }catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's singleton object failed", ex); } } // 放入factoryBeanObjectCache缓存 this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT)); } } return (object != NULL_OBJECT ? object : null); } }else { // 使用factoryBean创建bean,然后再执行所有的BeanPostProcessor(和上面一样) // 不同点是prototype这种情况的话,不会放到缓存中 Object object = doGetObjectFromFactoryBean(factory, beanName); if (object != null && shouldPostProcess) { try { object = postProcessObjectFromFactoryBean(object, beanName); }catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex); } } return object; } }
直接来看代码块16里第1处调用的方法:
代码块17 private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName) throws BeanCreationException { Object object; try { // 就是简单调用了FactoryBean的getObject而已,只不过if // 代码块的是特权调用,else里是直接调用 if (System.getSecurityManager() != null) { AccessControlContext acc = getAccessControlContext(); try { object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { @Override public Object run() throws Exception { return factory.getObject(); } }, acc); }catch (PrivilegedActionException pae) { throw pae.getException(); } }else { object = factory.getObject(); } }catch (FactoryBeanNotInitializedException ex) { throw new BeanCurrentlyInCreationException(beanName, ex.toString()); }catch (Throwable ex) { throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex); } // 如果结果object此时还是null,并且这个FactoryBean还是在创建的这个过程中,则 // 抛出异常,此时说明初始化流程是存在问题的 if (object == null && isSingletonCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException( beanName, "FactoryBean which is currently in creation returned null from getObject"); } return object; }
这段代码是也是段纸老虎代码,看着很长,其实很简单,就是调用了FactoryBean的getObject方法而已,我们再来看代码块16的if中调用的代码,注意真正被调用的方法在AbstractAutowireCapableBeanFactory中:
代码块18 @Override protected Object postProcessObjectFromFactoryBean(Object object, String beanName) { return applyBeanPostProcessorsAfterInitialization(object, beanName); } @Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { // 执行所有BeanPostProcessor的postProcessAfterInitialization方法 Object result = existingBean; // 遍历执行 for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { result = beanProcessor.postProcessAfterInitialization(result, beanName); if (result == null) { return result; } } return result; }
至此,代码块10中的3处就完了,是不是感觉费了很久功夫呢?其实阅读源码就是这样,方法中套方法,经常都是你看完了一个很长的方法,再回到原来的方法,发现其实只是这个方法中的一行代码,我早些时候经常都是边看边吐血,因为真的太难了,不过好在一遍又一遍的坚持了下来,完了还是很开心的。
代码块10.4
小小的吐槽完了,继续看代码块10中的第4处,这里主要是针对prototype的循环依赖检查,这个是当A中有B,B中有A并且A和B的scope都是prototype的时候会在这里抛异常,spring解决不了prototype的循环依赖,原因也简单,你想嘛,你想要一个新的A,创建A的时候发现A需要一个新的B,所以要去创建B,但是创建B的时候,又要一个新的A,然后就陷入无限循环,最后要么StackOverFlowException,要么OutOfMemoryError,所以spring就在这里直接抛异常了。
代码块10.5
接下来是代码块10的第5处调用的方法,这个方法是用来获取bean的原始名称的:
代码块19 protected String originalBeanName(String name) { String beanName = transformedBeanName(name); // 如果name中有"&",那就给beanName也加上“&” // 因为transformedBeanName中去掉了“&” if (name.startsWith(FACTORY_BEAN_PREFIX)) { beanName = FACTORY_BEAN_PREFIX + beanName; } return beanName; }
第一行的代码解释见代码块5,剩下的很简单了,我们继续代码块10中的第6处调用的方法:
代码块10.6
代码块20 protected void markBeanAsCreated(String beanName) { // alreadyCreated 是已经创建的和正准备去创建的集合 if (!this.alreadyCreated.contains(beanName)) { this.alreadyCreated.add(beanName); } }
依然是个很简单的方法,代码块10中第6处调用这个方法,是因为准备去创建这个bean了。我们继续代码块10中第7处,这下要讲这个之前代码块12和代码块2中跳过的getMergedLocalBeanDefinition(String name)方法了,我们先贴出来这个方法的代码哈:
代码块10.7
代码块21 // 首先调用的方法 protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException { // 看看缓存中有没有,如果有的话直接返回 RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName); if (mbd != null) { return mbd; } // 调用下面的方法 return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); } protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd) throws BeanDefinitionStoreException { // 继续调用下面的方法 return getMergedBeanDefinition(beanName, bd, null); } protected RootBeanDefinition getMergedBeanDefinition( String beanName, BeanDefinition bd, BeanDefinition containingBd) throws BeanDefinitionStoreException { // 加锁防止并发 synchronized (this.mergedBeanDefinitions) { // 这个是返回结果 RootBeanDefinition mbd = null; // Check with full lock now in order to enforce the same merged instance. // 之所以还在这里get一下,是因为防止从上面的方法到这里的时候已经有别的线程把这个RootBeanDefinition创建好了 // 现在在这个串行的操作中,如果没有get到,说明就是确实还没有 if (containingBd == null) { mbd = this.mergedBeanDefinitions.get(beanName); } // 若不存在于缓存中,则进行下一步操作 if (mbd == null) { if (bd.getParentName() == null) { // 如果没有父定义的BeanDefinition,则不需要合并,直接通过深克隆的方式 // 创建RootBeanDefinition if (bd instanceof RootBeanDefinition) { mbd = ((RootBeanDefinition) bd).cloneBeanDefinition(); } else { mbd = new RootBeanDefinition(bd); } } else { // 存在父定义BeanDefinition,递归着去和父定义的合并 BeanDefinition pbd; try { // 获取父BeanDefinition真正的名称 String parentBeanName = transformedBeanName(bd.getParentName()); if (!beanName.equals(parentBeanName)) { // 递归调用 pbd = getMergedBeanDefinition(parentBeanName); } else { if (getParentBeanFactory() instanceof ConfigurableBeanFactory) { // 强转再递归调用 pbd = ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(parentBeanName); } else { throw new NoSuchBeanDefinitionException(bd.getParentName(), "Parent name '" + bd.getParentName() + "' is equal to bean name '" + beanName + "': cannot be resolved without an AbstractBeanFactory parent"); } } } catch (NoSuchBeanDefinitionException ex) { throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName, "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex); } // 根据父定义深度拷贝一个新的 mbd = new RootBeanDefinition(pbd); // 用子覆盖父 mbd.overrideFrom(bd); } // 默认单例 if (!StringUtils.hasLength(mbd.getScope())) { mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON); } // 设置scope,此时containingBd还是null if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) { mbd.setScope(containingBd.getScope()); } // containingBd是null && this.cacheBeanMetadata && 该bean是否可以被缓存 // 这里这三个条件走到这块一般都成立了 if (containingBd == null && isCacheBeanMetadata() && isBeanEligibleForMetadataCaching(beanName)) { this.mergedBeanDefinitions.put(beanName, mbd); } } return mbd; } }
这个方法的代码不算难,但是为什么要把其他类型的BeanDefinition都转成RootBeanDefinition呢?因为RootBeanDefinition是被spring作为在运行时候的统一使用的BeanDefnition(即在创建bean实例时候使用的统一的BeanDefnition),里面还包含了解析过的构造方法缓存,方法参数缓存其他缓存信息,如果说其他类型的BeanDefnition都是用于把元数据(就是如xml或者注解)表达为spring可以认识的信息的话,那么RootBeanDefinition就是把spring已经认识出来的信息表达为了可以实际去使用的信息。
我们继续看代码块10中第8处方法调用的方法:
代码块10.8
代码块22 protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, Object[] args) throws BeanDefinitionStoreException { // 如果是抽象则抛出异常 if (mbd.isAbstract()) { throw new BeanIsAbstractException(beanName); } // 如果args不是null但是beanDefinition对应的类型却不是prototype,则抛出异常 // 这个是因为当args不是null的时候,代表需要动态参数实例化bean,而此时该bean的作用域只能是prototype if (args != null && !mbd.isPrototype()) { throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "Can only specify arguments for the getBean method when referring to a prototype bean definition"); } }
代码块22我没有标数字,我稍微解释一下这里面的第二处注释,方法参数args不为null的情况是当你调用了applicationContext中带参数的getbean方法或者是beanFactory中带参数的getbean方法时候,这里才不是null,但是高版本的spring已经把这个对参数检查去掉了。
代码块10.9
继续看代码块10中第9处,此时已经找到我们这个beanName对应的bean需要依赖的bean是哪些bean了,因此将依赖关系注册进去:
代码块23 public void registerDependentBean(String beanName, String dependentBeanName) { // 获取真正的bean名称 String canonicalName = canonicalName(beanName); // 这段代码是将beanName和dependentBeanName的依赖关系注册到dependentBeanMap中 // 注意这个是beanName依赖dependentBeanName synchronized (this.dependentBeanMap) { Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName); if (dependentBeans == null) { dependentBeans = new LinkedHashSet<String>(8); this.dependentBeanMap.put(canonicalName, dependentBeans); } dependentBeans.add(dependentBeanName); } // 这段代码是将beanName和dependentBeanName的依赖关系注册到dependentBeanMap中 // 注意这个是dependentBeanName依赖beanName,关系是反着的 // 就是说当A中有B,B中有A和C的时候,C中又有A,spring通过这两个map就能知道 // A依赖了B,而依赖A的有A和C synchronized (this.dependenciesForBeanMap) { Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(dependentBeanName); if (dependenciesForBean == null) { dependenciesForBean = new LinkedHashSet<String>(8); this.dependenciesForBeanMap.put(dependentBeanName, dependenciesForBean); } dependenciesForBean.add(canonicalName); } }
里面第一行注释调用的方法在本篇的代码块7已经讲过,其他的都很容易理解了,我们继续回过头来看代码块10中的第10处,在看这里调用的getSingleton方法之前,你需要注意到这个getSingleton方法和之前的不一样,此外,这个方法调用的时候所传的第二参数是个实现了ObjectFactory的匿名内部类,并且在它的实现里面调用了createBean方法,限于篇幅,createBean方法会在下一篇讲,不然估计你可能会晕的更厉害。我们来看这里的getSingleton方法,注意这个getSingleton和上面代码块8的不是一个方法:
代码块10.10
代码块24 public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "'beanName' must not be null"); synchronized (this.singletonObjects) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { // 如果当前beanFactory处在destruction状态中,则不允许创建bean // 这个状态指的是beanFactory执行了destroySingletons方法,即applicationContext执行close方法会调用到这个方法 if (this.singletonsCurrentlyInDestruction) { throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while the singletons of this factory are in destruction " + "(Do not request a bean from a BeanFactory in a destroy method implementation!)"); } if (logger.isDebugEnabled()) { logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); } // 1. 创建单例前的检查 beforeSingletonCreation(beanName); // suppressedExceptions用户记录在创建期间出现的异常 boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<Exception>(); } try { // 调用ObjectFactory来创建bean singletonObject = singletonFactory.getObject(); }catch (BeanCreationException ex) { if (recordSuppressedExceptions) { for (Exception suppressedException : this.suppressedExceptions) { ex.addRelatedCause(suppressedException); } } throw ex; }finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } // 2. 创建单例后的检查 afterSingletonCreation(beanName); } // 将创建出来的bean放到缓存中 addSingleton(beanName, singletonObject); } return (singletonObject != NULL_OBJECT ? singletonObject : null); } }
我们来看上面的代码块中1,创建单例前的检查:
代码块25 protected void beforeSingletonCreation(String beanName) { // 检查bean是否要包含在检查已经创建的集合中,如果不是,则看bean是否在创建中 if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } }
然后是代码块24中的2,创建单例后的检查:
代码块26 protected void afterSingletonCreation(String beanName) { // 检查bean是否要包含在检查已经创建的集合中,如果不是,则从正在创建的集合中移除, // 移除失败则抛异常 if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) { throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation"); } }
getSingleton方法完了,我们继续回到代码块10看11处的创建prototype前的检查:
代码块10.11
代码块27 @SuppressWarnings("unchecked") protected void beforePrototypeCreation(String beanName) { // 从当前线程正在创建的prototype中拿所有的正在创建的集合 Object curVal = this.prototypesCurrentlyInCreation.get(); // 如果curlVal是空,则设置当前bean为正在创建的bean if (curVal == null) { this.prototypesCurrentlyInCreation.set(beanName); // 如果不是空并且是个String(代表有一个在创建中),则创建集合,并且把curVal // 和当前beanName都加进去 } else if (curVal instanceof String) { Set<String> beanNameSet = new HashSet<String>(2); beanNameSet.add((String) curVal); beanNameSet.add(beanName); this.prototypesCurrentlyInCreation.set(beanNameSet); // 这种的说明是有两个以上的在创建,直接加入正在创建的集合中去 } else { Set<String> beanNameSet = (Set<String>) curVal; beanNameSet.add(beanName); } }
接下来是代码块10看12处:
代码块10.12
代码块29 @SuppressWarnings("unchecked") protected void afterPrototypeCreation(String beanName) { // 获取正在创建的prototype的集合 Object curVal = this.prototypesCurrentlyInCreation.get(); // 如果是String则直接remove掉 if (curVal instanceof String) { this.prototypesCurrentlyInCreation.remove(); } // 如果是set则从set中删除 else if (curVal instanceof Set) { Set<String> beanNameSet = (Set<String>) curVal; beanNameSet.remove(beanName); if (beanNameSet.isEmpty()) { this.prototypesCurrentlyInCreation.remove(); } } }
至此doGetBean方法已经讲完,下一篇,我们开始createBean方法