this . readerContext .getRegistry(), true );
}
else {
// 如果 Bean 为空,就在这里注册一个 Class 全局限定名
beanName = this . readerContext .generateBeanName(beanDefinition);
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName != null &&
beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
! this . readerContext .getRegistry().isBeanNameInUse(beanClassName)) {
aliases.add(beanClassName);
}
}
if ( logger .isDebugEnabled()) {
logger .debug( "Neither XML 'id' nor 'name' specified - " +
"using generated bean name [" + beanName + "]" );
}
}
catch (Exception ex) {
error(ex.getMessage(), ele);
return null ;
}
}
String[] aliasesArray = StringUtils.toStringArray (aliases);
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
}
return null ;
哈哈哈,我快乐疯了,就在上面这段代码里, AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean).
public AbstractBeanDefinition parseBeanDefinitionElement(
Element ele, String beanName, BeanDefinition containingBean) {
this . parseState .push( new BeanEntry(beanName));
String className = null ;
if (ele.hasAttribute( CLASS_ATTRIBUTE )) {
className = ele.getAttribute( CLASS_ATTRIBUTE ).trim();
}
try {
String parent = null ;
if (ele.hasAttribute( PARENT_ATTRIBUTE )) {
parent = ele.getAttribute( PARENT_ATTRIBUTE );
}
// 创建实例
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
// 将 XML 中的属性写进入
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
bd.setDescription(DomUtils.getChildElementValueByTagName (ele, DESCRIPTION_ELEMENT ));
// 都是把 XML 里面的东西写进去!
parseMetaElements(ele, bd);
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
parseConstructorArgElements(ele, bd);
parsePropertyElements(ele, bd);
parseQualifierElements(ele, bd);
bd.setResource( this . readerContext .getResource());
bd.setSource(extractSource(ele));
return bd;
}
catch (ClassNotFoundException ex) {
….
}
事情已经很清楚了,但是我又在想一个 Spring 应用程序一般会用到很多 XML 配置文件的,也有很多应用类的,应该有能让 Spring 在一个集中的能快速找到这些 BeanDefintion 的地方吧?
(在分析代码的过程中,你最好还是要不断的思考,说不定能提前预知一些事情哪!!!)回到 DefaultBeanDefinitionDocumentReader 的 doRegisterBeanDefinitions(Element root) 方法中:
preProcessXml(root);
parseBeanDefinitions(root, this . delegate );
postProcessXml(root);
在你看完这些方法的实现,你就清楚了,这里不再挨个看了,直接给出答案!
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
//DeanDefinitionHolder 实际是 BeanDefintion 的包装类,持有 BeanDefinitionHolder ,实际上也就拥有了
//BeanDefinition 的创建核心
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null ) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder );
try {
// Register the final decorated instance.
//BeanDEfintion 在这里注册
BeanDefinitionReaderUtils.registerBeanDefinition (bdHolder , getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error( "Failed to register bean definition with name '" +
bdHolder .getBeanName() + "'" , ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered( new BeanComponentDefinition(bdHolder ));
}
}
BeanDefinitionReaderUtils.registerBeanDefinition :
public static void registerBeanDefinition (
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any.
String[] aliases = definitionHolder.getAliases();
if (aliases != null ) {
for (String aliase : aliases) {
registry.registerAlias(beanName, aliase);
}
}
}
发现使用了 BeanDefinitionRegistry 类,从名字来看,注册有关,在查询一些材料时,我是知道这个注册是用来干什么的,就是把 BeanDefinition 方法一方地方,一个能供 Spring 其他类找到 BeanDefinition 的地方!这个类是一个接口,它的实现居然是 DefaultListableBeanFactory( 按 F4 键后看到的类继承结构后分析出来的 )! 我在它里面发现了这个:
public void registerBeanDefinition (String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText (beanName, "Bean name must not be empty" );
Assert.notNull (beanDefinition, "BeanDefinition must not be null" );
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed" , ex);
}
}
synchronized ( this . beanDefinitionMap ) {
Object oldBeanDefinition =
this . beanDefinitionMap .get(beanName);
if (oldBeanDefinition != null ) {
if (! this . allowBeanDefinitionOverriding ) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
"': There is already [" + oldBeanDefinition + "] bound." );