【Spring源码】20. Bean的创建过程(5)

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第20天,点击查看活动详情

当当当当~我们紧接上篇进入真正要创建Bean的逻辑┏ (^ω^)=,我们先看下下面的getSingleton()方法:

值得注意的是,这里的getSingleton()跟之前介绍过的那个getSingleton()不是同一个哦(记不记得哪里也出现过啦(b_d),就是preInstantiateSingletons()方法中进行isFactoryBean()判断方法中呀゚▽゚>)

但其实这两个方法并不是同一个方法,不过他们都是DefaultSingletonBeanRegistry.java中的重载方法

第一个参数都是beanName,第二个参数不同,这里的getSingleton()的第二个参数是ObjectFactory<?>(也就是上面介绍的那个函数式接口),而且在getSingleton(String beanName, ObjectFactory<?> singletonFactory)中只查询了一级缓存singletonObjects,而getSingleton(String beanName, boolean allowEarlyReference) 中还涉及到了二级缓存earlySingletonObjects,以及三级缓存singletonFactories(更详细的三级缓存相关介绍可以查看【Spring源码】2.试个水先~Debug找到传说中的三级缓存(图解向,堆图预警))

当前执行到这里的getSingleton(String beanName, ObjectFactory<?> singletonFactory)方法的第二个参数此时传入的是一个匿名内部类,方法的第二个参数就是以lambda表达式的方式传入(函数式接口可以被隐式转换为 lambda 表达式),即下图阴影部分:

() -> {
      try {
         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.
         destroySingleton(beanName);
         throw ex;
      }
   }
复制代码

进入getSingleton()方法后可以看到:

这个匿名内部类是ObjectFactory,而ObjectFactory是一个函数式接口(函数式接口(Functional Interface,被@FunctionalInterface修饰)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口),ObjectFactory中定义了一个返回对象的工厂方法,当调用其中的getObject方法的时候,才会将实际传递的匿名内部类中的实际逻辑进行执行。

在这里是指只有当调用了ObjectFactorygetObject()方法,才会执行当作入参传入的逻辑,即执行上面图中的阴影部分中的createBean()

So,我们要开始create bean啦*・゜゚・:.。..。.:・'(゚▽゚)'・:.。. .。.:・゜゚・*

猜你喜欢

转载自juejin.im/post/7133159509182775303