阅读之前要注意的东西:本文就是主打流水账式的源码阅读,主导的是一个参考,主要内容需要看官自己去源码中验证。全系列文章基于 spring 源码 5.x 版本。
写在开始前的话:
阅读spring 源码实在是一件庞大的工作,不说全部内容,单就最基本核心部分包含的东西就需要很长时间去消化了:
实际上我在博客里贴出来的还只是一部分内容,更多的内容,我放在了个人,fork自 spring 官方源码仓了; 而且对源码的学习,必须是要跟着实际代码层层递进的,不然只是干巴巴的文字味同嚼蜡。
这个仓设置的公共仓,可以直接拉取。
不管是何种作用域的bean 创建,最终都会指向: “如何从零开始创建bean”,而这个话题前文已经讲解过了。
本文重点介绍,单例作用域的bean 在这个过程中的动作有何异同。
这里显然是定义了一个回调操作:
sharedInstance 声明的类型是 Object
Object sharedInstance;
看 sharedInstance 的定义,重点看它的第二个参数,经典匿名内部类写法。这里 createBean() 接收 了bean 相关配置信息;
当在 getSingleton(beanName, ObjectFactory) 方法内部调用 ObjectFactory 的 getObject() 方法时,这些参数将会真正登场。
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { public Object getObject() throws BeansException { try { // 准备完成后回调 由子类 AbstractAutowireCapableBeanFactory 实现方法 return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. // 出错,单例工厂销毁该 bean destroySingleton(beanName); throw ex; } } });
复制
接下来我们先看看 getSingleton(beanName, ObjectFactory) 干了什么:
口头挨个介绍过于干巴巴了,下边直接贴出加了注释的代码:
/** * Return the (raw) singleton object registered under the given name, * creating and registering a new one if none registered yet. * * @param beanName the name of the bean * @param singletonFactory the ObjectFactory to lazily create the singleton * with, if necessary * @return the registered singleton object */ 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) { // 新创建bean,单例对象池中不存在,否则直接方法返回 if (this.singletonsCurrentlyInDestruction) { // bean 已经被废弃,不能再加载它,抛异常退出 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 (logger.isDebugEnabled()) { logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); } // 进行bean重复创建的校验,如果当前bean已经在创建流程中抛异常,众所周知单例bean必须唯一 beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } try { // 校验通过后,调用 ObjectFactory 的 getObject() 进一步回调 createBean() 方法 singletonObject = singletonFactory.getObject(); // 有没有觉得这也太简单了?其实不然,bean 加载的重头戏还在后边: createBean() newSingleton = true; } catch (IllegalStateException ex) { // Has the singleton object implicitly appeared in the meantime -> // if yes, proceed with it since the exception indicates that state. singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { throw ex; } } catch (BeanCreationException ex) { if (recordSuppressedExceptions) { for (Exception suppressedException : this.suppressedExceptions) { ex.addRelatedCause(suppressedException); } } throw ex; } finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } // bean 首次加载后再次校验,它是否是真的第一次被加载 afterSingletonCreation(beanName); } if (newSingleton) { // 如果是一个新的单例bean,那么把它假如缓存中,从这里进去看到的一定会是:三级缓存 addSingleton(beanName, singletonObject); } } return singletonObject; } }
复制
针对单例作用域bean 的创建,这里会根据缓存进行判断,需要保证全局唯一。
getSingleton() 返回 sharedInstance时,实际上最终得到的是回调: createBean()的返回结果
sharedInstance 就只可能有两种类型: 普通bean 或者 FactoryBean
然后进入如下逻辑,根据 sharedInstance 提取实际的bean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);