5.3从bean的实例中获取对象
让我们尝试打开"5.bean的加载 - 3) bean的实例化的大门":
AbstractBeanFactory protected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { // Don't let calling code try to dereference the factory if the bean isn't a factory. //如果指定的name是工厂相关的(以&为前缀),那么返回工厂实例FactoryBean if (BeanFactoryUtils.isFactoryDereference(name)) { if (beanInstance instanceof NullBean) { return beanInstance; } //并且beanInstance又不是FactoryBean类型则验证不通过 if (!(beanInstance instanceof FactoryBean)) { throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass()); } if (mbd != null) { mbd.isFactoryBean = true; } return beanInstance; } // Now we have the bean instance, which may be a normal bean or a FactoryBean. // If it's a FactoryBean, we use it to create a bean instance, unless the // caller actually wants a reference to the factory. //如果beanInstance不是FactoryBean的实例,那么返回此实例 //如果是FactoryBean,又没有&前缀,通过FactoryBean的getObject获取实例 if (!(beanInstance instanceof FactoryBean)) { return beanInstance; } //加载FactoryBean Object object = null; if (mbd != null) { mbd.isFactoryBean = true; } else { //尝试从缓存中加载bean object = getCachedObjectForFactoryBean(beanName); } if (object == null) { // Return bean instance from factory. //到这里已经明确知道beanInstance一定是FactoryBean类型 FactoryBean<?> factory = (FactoryBean<?>) beanInstance; // Caches object obtained from FactoryBean if it is a singleton. //containsBeanDefinition检测beanDefinitionMap中也就是所有已经加载的类中 //检测是否定义beanName if (mbd == null && containsBeanDefinition(beanName)) { //将存储XML配置文件的GernericBeanDefinition转换为RootBeanDefinition //如果指定beanName是子bean的话同时合并父类相关属性 mbd = getMergedLocalBeanDefinition(beanName); } //是否是用户定义的而不是应用程序本身定义的 boolean synthetic = (mbd != null && mbd.isSynthetic()); object = getObjectFromFactoryBean(factory, beanName, !synthetic); } return object; }
大致逻辑:
首先Object beanInstance可能是BeanFactory,也可能已经是我们需要的实例。
1.如果beanName包含了 "&" 前缀,那么返回工厂实例Factory。
2.如果beanInstance不是Factory的实例,那么返回此实例。
3.如果beanInstance是Factory的实例,又不包含 "&" 前缀,通过FactoryBean的getObject获取实例返回,委托给getObjectFromFactoryBean()处理。
FactoryBeanRegistrySupport protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) { //如果是单例模式并且singletonObjects包含了beanName if (factory.isSingleton() && containsSingleton(beanName)) { synchronized (getSingletonMutex()) { Object object = this.factoryBeanObjectCache.get(beanName); if (object == null) { object = doGetObjectFromFactoryBean(factory, beanName); // Only post-process and store if not put there already during getObject() call above // (e.g. because of circular reference processing triggered by custom getBean calls) //判断在getObject()期间缓存中是否设置了Bean //因为factoryBeanObjectCache是单例的,可以同时被别人操作 Object alreadyThere = this.factoryBeanObjectCache.get(beanName); if (alreadyThere != null) { object = alreadyThere; } else { if (shouldPostProcess) { if (isSingletonCurrentlyInCreation(beanName)) { // Temporarily return non-post-processed object, not storing it yet.. return object; } beforeSingletonCreation(beanName); try { //调用ObjectFactory的后处理 object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's singleton object failed", ex); } finally { afterSingletonCreation(beanName); } } if (containsSingleton(beanName)) { this.factoryBeanObjectCache.put(beanName, object); } } } return object; } } 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; } }
这里要注意的是第二处:
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);因为doGetObjectFromFactoryBean获取getObject()期间缓存中可能设置好了我们需要的Bean。因为factoryBeanObjectCache是单例的,可以同时被别人操作。
FactoryBeanRegistrySupport private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, 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 { //直接调用getObject()方法 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); } // Do not accept a null value for a FactoryBean that's not fully // initialized yet: Many FactoryBeans just return null then. if (object == null) { if (isSingletonCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException( beanName, "FactoryBean which is currently in creation returned null from getObject"); } object = new NullBean(); } return object; }
总的来说:
1.如果beanName包含了 "&" 前缀,那么返回工厂实例Factory。
2.如果beanInstance不是Factory的实例,那么返回此实例。
3.如果beanInstance是Factory的实例,又不包含 "&" 前缀,通过FactoryBean的getObject获取实例返回,委托给getObjectFromFactoryBean()处理。

浙公网安备 33010602011771号