[Spring]Spring中的bean定义解析

313 阅读1分钟

阅读Spring getBean的时候,发现在createBean()都是依赖于RootBeanDefinition来创建的bean. 

protected <T> T doGetBean(final String name, final Class<T> requiredType, 
                        final Object[] args, boolean typeCheckOnly)   throws BeansException {

     // something do before createBean
     // .......
     // get BeanDefinition
     final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
     checkMergedBeanDefinition(mbd, beanName, args);

     // createBean according to RootBeanDefinition
     if(mbd.isSingleton()){
         sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
		@Override
		public Object getObject() throws BeansException {
		    try {
			return createBean(beanName, mbd, args);
		     }catch (BeansException ex) {
		        // destory 
			destroySingleton(beanName);
			throw ex;
		      }
	        }
	    });
	 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); 
     } else if(mbd.isPrototype()) {
        // 大致逻辑同上
     } else {
        // other scope bean, 大致逻辑和singleton/prototype一样
     }
}

既然知道了bean instance都是根据BeanDefinition来创建的,那么

1.  BeanDefinition是从哪里来的?

在doGetBean()中获取bean对应的BeanDefinition的语句:    final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);(下面合并beanDefinition的语句暂时不管,后面有机会再说)

getMergedLocalBeanDefinition(beanName):

protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName)
             throws BeansException {
    // Quick check on the concurrent map first, with minimal locking. 
    RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName); 
    if (mbd != null) {
     return mbd;
     } 
    return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); 
}

可以看到在AbstractBeanFactory中定义了 this.mergedBeanDefinitions来保存Merge BeanDefinition.  获取原始的beanDefinition还是通过getBeanDefinition(beanName).

getBeanDefinition(beanName) 在AbstractBeanFactory中是抽象方法, 在子类DefaultListableBeanFactory中被实现:

@Override
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
   BeanDefinition bd = this.beanDefinitionMap.get(beanName);  
 if (bd == null) {    
      if (this.logger.isTraceEnabled()) {     
           this.logger.trace("No bean named '" + beanName + "' found in " + this);     
      }    
      throw new NoSuchBeanDefinitionException(beanName);  
  }  
 return bd;
}

最终可以看到在DefaultListableBeanFactory中是用的 beanDefinitionMap来保存的BeanDefinition的.  (ps: 最终在ApplicationContext中使用的也是DefaultListableBeanFactory)

那么,DefaultListableBeanFactory中beanDefinitionMap中的数据又是从哪里来的. 

通过追踪beanDefinitionMap.put的调用,可以看到beanDefainition.put()在registerBeanDefinition方法中被调用.  而这个方法是实现自BeanDefinitionRegistry的. 

So, beanDefinitionMap中的beanDefinition都是通过实现自BeanDefinitionRegistry的接口中注册进来的.

通过上面的阅读,我们已经知道了beanDefinition是通过何种方式注册的以及如何被使用的, 那么:

2. Spring XML中关于bean的定义是如何被解析的?