距离真相还差两步了,坚持就是胜利,我们继续看getObjectFromFactoryBean()的源码
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) { // 此处调用 FactoryBean 的isSingleton()方法,判断是否是一个单列 // 如果是单例的,走if内部,获取到对象后,会保存到factoryBeanObjectCache缓存中,以便后续使用 if (factory.isSingleton() && containsSingleton(beanName)) { synchronized (getSingletonMutex()) { // 检查缓存中是否已经存在 Object object = this.factoryBeanObjectCache.get(beanName); if (object == null) { // 调用最后一个方法,执行FactoryBean 的 getObject()方法获取对象 object = doGetObjectFromFactoryBean(factory, beanName); // 再次检查缓存 Object alreadyThere = this.factoryBeanObjectCache.get(beanName); if (alreadyThere != null) { object = alreadyThere; } else { // ... 省略代码 ... if (containsSingleton(beanName)) { // 将获取的对象放入factoryBeanObjectCache缓存中,以便后续使用 this.factoryBeanObjectCache.put(beanName, object); } } } return object; } } // 如果不是单例的,每次获取的对象直接返回,不会放入缓存中,所以每次都会调用getObject()方法 else { Object object = doGetObjectFromFactoryBean(factory, beanName); if (shouldPostProcess) { try { object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex); } } return object; } }根据上面的流程,终于来到了最后一步
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName) throws BeanCreationException { Object object; try { if (System.getSecurityManager() != null) { AccessControlContext acc = getAccessControlContext(); try { object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { // 直接调用 FactoryBean 接口的 getObject()方法获取实例对象 object = factory.getObject(); } } catch (FactoryBeanNotInitializedException ex) { throw new BeanCurrentlyInCreationException(beanName, ex.toString()); } // ... 省略代码 ... return object; }经过如此多的代码,spring终于帮我们获取到Bike对象实例
通过BikeFactoryBean来获取Bike类的实例时,spring先获取Bike类型对应的beanName(bikeFactoryBean),然后根据beanName获取到工厂Bean实例本身(BikeFactoryBean),最终spring会调用BikeFactoryBean 的 getObject()方法来获取Bike对象实例。并且根据 BikeFactoryBean 实例的 isSingleton() 方法来判断Bike类型的实例是否时单例的,依此来决定要不要将获取的Bike对象放入到缓存中,以便后续使用。
总结本文主要讲解了如何通过 FactoryBean接口向spring容器中注入组件,通过简单的案例进行模拟,并根据案例对源码的执行过程进行跟踪,分析了FactoryBean接口的执行过程。
另外,在每一次跟踪spring源码时,都会有新的收获。在spring庞大的体系下,只有定位好自己的目标,明确自己的需求,才不会被spring无限的代码所淹没。
学习永远都不是一件简单的事情,可以有迷茫,可以懒惰,但是前进的脚步永远都不能停止。
不积跬步,无以至千里;不积小流,无以成江海;