主代码
类AbstractBeanFactory
protected <T> T doGetBean(......){
// ......
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
// ......
}
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
// 若name传递的是如“&student”且该bean不是FactoryBean,抛出异常
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
// 如果beanInstance不是FactoryBean,是一个普通的Bean,直接返回
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
Object object = null;
if (mbd == null) {
// 尝试从缓存中获取Bean
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
详细分析
getCachedObjectForFactoryBean这个方法放在FactoryBeanRegistrySupport类中,FactoryBeanRegistrySupport类在DefaultSingletonBeanRegistry类的基础上(继承于DefaultSingletonBeanRegistry类)增加了对FactoryBean的特殊处理(从命名上可以看出),下面是从缓存中获取FactoryBean:
private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<String, Object>(16); protected Object getCachedObjectForFactoryBean(String beanName) { Object object = this.factoryBeanObjectCache.get(beanName); return (object != NULL_OBJECT ? object : null); }
问题来了,FactoryBean什么时候放到缓存中呢?
是由本类(FactoryBeanRegistrySupport)的getObjectFromFactoryBean方法设置进去的,该方法内若从缓存中获取不到Bean,就会调用factory.getObject()获取Bean,并put到factoryBeanObjectCache中(第一次获取factoryBeanObjectCache一定获取不到的)。
接下来看下containsBeanDefinition(beanName)方法,定位到DefaultListableBeanFactory类中,该类是bean加载的核心部分,是Spring注册及加载的默认实现,功能强大。
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256); public boolean containsBeanDefinition(String beanName) { Assert.notNull(beanName, "Bean name must not be null"); return this.beanDefinitionMap.containsKey(beanName); }
从代码中可以看出,beanDefinitionMap是否包含beanName的key,beanDefinitionMap是什么时候put进去值的时候,分析spring配置文件的加载方式不难发现,所有被扫描的Bean都会注册到beanDefinitionMap中,具体参考该类中registerBeanDefinition方法。
再看getMergedLocalBeanDefinition(beanName)方法,该方法的作用是获取子Bean与父Bean合并后RootBeanDefinition,即如果beanName有父Bean,需要把父Bean与该Bean合并成一个RootBeanDefinition(属性合并等等,参考AbstractBeanDefinition的overrideFrom方法,同时参考parent标签的使用)
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException { // 尝试从缓存中获取RootBeanDefinition RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName); if (mbd != null) { return mbd; } // 若获取失败,调用以下方法来获取RootBeanDefinition 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 { // 对缓存map上锁 synchronized (this.mergedBeanDefinitions) { RootBeanDefinition mbd = null; // containingBd可以看作是内部Bean if (containingBd == null) { mbd = this.mergedBeanDefinitions.get(beanName); } if (mbd == null) { if (bd.getParentName() == null) { // 没有父Bean if (bd instanceof RootBeanDefinition) { mbd = ((RootBeanDefinition) bd).cloneBeanDefinition(); } else { mbd = new RootBeanDefinition(bd); } } else { // 有父Bean BeanDefinition pbd; // 获取父Bean的名称 String parentBeanName = transformedBeanName(bd.getParentName()); if (!beanName.equals(parentBeanName)) { pbd = getMergedBeanDefinition(parentBeanName); } else { // 获取父Bean的BeanFactory,并从中获取父BeanDefinition(流程同子BeanDefinition的获取过程) BeanFactory parent = getParentBeanFactory(); if (parent instanceof ConfigurableBeanFactory) { pbd = ((ConfigurableBeanFactory)parent).getMergedBeanDefinition(parentBeanName); } else { // 抛出异常(父Bean工厂不是AbstractBeanFactory类型) } } // 深度拷贝 mbd = new RootBeanDefinition(pbd); // 父子BeanDefinition属性合并 mbd.overrideFrom(bd); } // Set default singleton scope, if not configured before. if (!StringUtils.hasLength(mbd.getScope())) { mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON); } if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) { mbd.setScope(containingBd.getScope()); } if (containingBd == null && isCacheBeanMetadata()) { this.mergedBeanDefinitions.put(beanName, mbd); } } return mbd; } }
关于synthetic的意义:该BeanDefinition是不是应用(这一点可讨论,感觉说是编译器合成的比较贴切)自己拥有并生成的,一般自定义的Bean都是返回false,由应用合成的返回true,下面代码:若取到的Bean是自定义的返回false,若是应用自己合成的返回true
boolean synthetic = (mbd != null && mbd.isSynthetic());
看最后一段代码,真正的获取Bean,直接分析代码比较好说,为了分析,省略了异常
// !synthetic = true(自定义的Bean) object = getObjectFromFactoryBean(factory, beanName, !synthetic);
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) { if (factory.isSingleton() && containsSingleton(beanName)) { synchronized (getSingletonMutex()) { // 从缓存中获取,factoryBeanObjectCache存放<FactoryBean名称,Object> Object object = this.factoryBeanObjectCache.get(beanName); if (object == null) { // 缓存中获取不到,从factory中获取 object = doGetObjectFromFactoryBean(factory, beanName); // 有可能当执行doGetObjectFromFactoryBean函数时,Bean正在创建,所以此时再获取一下 Object alreadyThere = this.factoryBeanObjectCache.get(beanName); if (alreadyThere != null) { object = alreadyThere; } else { if (object != null && shouldPostProcess) { // 后处理Bean,不再分析 object = postProcessObjectFromFactoryBean(object, beanName); } // 放到缓存中 this.factoryBeanObjectCache.put(beanName, (object != null ? object :NULL_OBJECT)); } } // 返回结果 return (object != NULL_OBJECT ? object : null); } } else { // 获取Bean Object object = doGetObjectFromFactoryBean(factory, beanName); if (object != null && shouldPostProcess) { // 后处理 object = postProcessObjectFromFactoryBean(object, beanName); } return object; } }
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName) throws BeanCreationException { Object object; if (System.getSecurityManager() != null) { AccessControlContext acc = getAccessControlContext(); object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { @Override public Object run() throws Exception { return factory.getObject(); } }, acc); } else { object = factory.getObject(); } // Do not accept a null value for a FactoryBean that's not fully initialized yet: Many FactoryBeans just return null then. if (object == null && isSingletonCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName, "FactoryBean which is currently in creation returned null from getObject"); } return object; }
至此,整个从FactoryBean中获取BeanDefinition完成。