上文说到Document已经加载完毕,此时到了Spring注册BeanDefinition的时候。下面就一块儿来探究下Spring是怎么把Xml文档注册成BeanDefinition的吧。
registerBeanDefinitions方法
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { //1. 建立BeanDefinitionDocumentReader BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader(); //2. 设置documentReader的环境 documentReader.setEnvironment(getEnvironment()); //3. 查询以前注册的BeanDefinition的个数 int countBefore = getRegistry().getBeanDefinitionCount(); //4. 开始注册BeanDefinition,注意里面建立了一个Reader上下文 documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); //5. 计算这次注册的BeanDefinition的个数 return getRegistry().getBeanDefinitionCount() - countBefore; }
使用BeanUtils建立一个DefaultBeanDefinitionDocumentReader对象,用于解析成BeanDefinition对象
private Class<?> documentReaderClass = DefaultBeanDefinitionDocumentReader.class; //建立一个BeanDefinitionDocumentReader,此处使用的是DefaultBeanDefinitionDocumentReader protected BeanDefinitionDocumentReader createBeanDefinitionDocumentReader() { //利用反射机制,调用DefaultBeanDefinitionDocumentReader的构造函数,而后建立一个实例返回 return BeanDefinitionDocumentReader.class.cast(BeanUtils.instantiateClass(this.documentReaderClass)); }
建立一个XmlReaderContext设置了命名空间解析器为DefaultNamespaceHandlerResolverjava
protected XmlReaderContext createReaderContext(Resource resource) { if (this.namespaceHandlerResolver == null) { this.namespaceHandlerResolver = createDefaultNamespaceHandlerResolver(); } return new XmlReaderContext(resource, this.problemReporter, this.eventListener, this.sourceExtractor, this, this.namespaceHandlerResolver); } protected NamespaceHandlerResolver createDefaultNamespaceHandlerResolver() { return new DefaultNamespaceHandlerResolver(getResourceLoader().getClassLoader()); }
用来处理不一样的命名空间的解析器,这些映射规则是配置在META-INF/spring.handlers文件中(见附图)好比对于xmlns为http://www.springframework.org/schema/c的命名空间的处理器为org.springframework.beans.factory.xml.SimpleConstructorNamespaceHandlernode
public static final String DEFAULT_HANDLER_MAPPINGS_LOCATION = "META-INF/spring.handlers"; public DefaultNamespaceHandlerResolver(ClassLoader classLoader) { //设置类加载器和handlerMapping文件的位置 this(classLoader, DEFAULT_HANDLER_MAPPINGS_LOCATION); } public DefaultNamespaceHandlerResolver(ClassLoader classLoader, String handlerMappingsLocation) { Assert.notNull(handlerMappingsLocation, "Handler mappings location must not be null"); this.classLoader = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader()); this.handlerMappingsLocation = handlerMappingsLocation; }
注册beanDefinition
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) { this.readerContext = readerContext; logger.debug("Loading bean definitions"); //获取xml的根元素<beans> Element root = doc.getDocumentElement(); //注册BeanDefinition doRegisterBeanDefinitions(root); } protected void doRegisterBeanDefinitions(Element root) { //获取 profile 属性值,我此处并无设置此属性值,因此使用的是默认的 String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE); //若是有配置profile,则进入 if (StringUtils.hasText(profileSpec)) { //将profile放入一个数组中 //profile能够配置多个,中间以MULTI_VALUE_ATTRIBUTE_DELIMITERS(,或;)分隔 String[] specifiedProfiles = StringUtils.tokenizeToStringArray( profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS); //判断环境是否接受此profile数组,若是环境中不容许就直接返回,再也不进行注册 //这就是为何pfofile起做用的缘由,和环境中的prfile不一致的配置,不会被Spring注册到容器中 if (!getEnvironment().acceptsProfiles(specifiedProfiles)) { return; } } // Any nested <beans> elements will cause recursion in this method. In // order to propagate and preserve <beans> default-* attributes correctly, // keep track of the current (parent) delegate, which may be null. Create // the new (child) delegate with a reference to the parent for fallback purposes, // then ultimately reset this.delegate back to its original (parent) reference. // this behavior emulates a stack of delegates without actually necessitating one. //任何嵌套的<beans>元素都将致使此方法中的递归。在为了正确地传播和保存<beans>缺省-*属性,跟踪当前(父)委托,它可能为空。建立新的(子)委托,该委托具备对父委托的引用,用于备份,而后最终将this.delegate重置回其原始(父)引用。这种行为模拟了一堆委托,实际上并不须要委托。这是直接翻译的,可能比较书面语。 //口语化的描述是,由于在递归解析<beans>中,为了正确的保持BeanDefinitionParserDelegate的引用关系,因此首先取出DefaultBeanDefinitionDocumentReader委托类暂存起来,而后建立一个新的委托类使用,最后再还原为以前的委托类。 //获取此DefaultBeanDefinitionDocumentReader的解析委托类 BeanDefinitionParserDelegate parent = this.delegate; //利用现有的委托类(可能为null),建立一个新的委托类 this.delegate = createDelegate(this.readerContext, root, parent); //预处理root,当前是空实现,可自行扩展 preProcessXml(root); //真正的处理root,并注册,详细的见下一小节《parseBeanDefinitions》 parseBeanDefinitions(root, this.delegate); //后处理root,当前是空实现,可自行扩展 postProcessXml(root); this.delegate = parent; } //辅助方法分析 //建立一个新的委托类BeanDefinitionParserDelegate // protected BeanDefinitionParserDelegate createDelegate(XmlReaderContext readerContext, Element root, BeanDefinitionParserDelegate parentDelegate) { //目前createHelper返回的值都是null BeanDefinitionParserDelegate delegate = createHelper(readerContext, root, parentDelegate); //目前都会进入此判断内 if (delegate == null) { //建立一个新的BeanDefinitionParserDelegate delegate = new BeanDefinitionParserDelegate(readerContext, getEnvironment()); //初始化,并经过readerContext分发一个开始注册BeanDefinition的事件 delegate.initDefaults(root, parentDelegate); } return delegate; } //BeanDefinitionParserDelegate.initDefaults //默认的文档BeanDefinition private final DocumentDefaultsDefinition defaults = new DocumentDefaultsDefinition(); public void initDefaults(Element root, BeanDefinitionParserDelegate parent) { //给defaults设置初始值 populateDefaults(this.defaults, (parent != null ? parent.defaults : null), root); //分发一个defaultsRegistered事件 this.readerContext.fireDefaultsRegistered(this.defaults); } //读取<beans>中配置的属性,并设置到defaults中 protected void populateDefaults(DocumentDefaultsDefinition defaults, DocumentDefaultsDefinition parentDefaults, Element root) { //设置 default-lazy-init , //值为default时,若是父节点不是null时,继承父节的属性值,不然为false String lazyInit = root.getAttribute(DEFAULT_LAZY_INIT_ATTRIBUTE); if (DEFAULT_VALUE.equals(lazyInit)) { lazyInit = parentDefaults != null ? parentDefaults.getLazyInit() : FALSE_VALUE; } defaults.setLazyInit(lazyInit); //设置 default-merge //值为default时,若是父节点不是null时,继承父节的属性值,不然为false String merge = root.getAttribute(DEFAULT_MERGE_ATTRIBUTE); if (DEFAULT_VALUE.equals(merge)) { merge = parentDefaults != null ? parentDefaults.getMerge() : FALSE_VALUE; } defaults.setMerge(merge); //设置 default-autowire //值为default时,若是父节点不是null时,继承父节的属性值,不然为no String autowire = root.getAttribute(DEFAULT_AUTOWIRE_ATTRIBUTE); if (DEFAULT_VALUE.equals(autowire)) { autowire = parentDefaults != null ? parentDefaults.getAutowire() : AUTOWIRE_NO_VALUE; } defaults.setAutowire(autowire); // don't fall back to parentDefaults for dependency-check as it's no // longer supported in <beans> as of 3.0. Therefore, no nested <beans> // would ever need to fall back to it. //设置 default-dependency-check ,不用检查父节点的值了 defaults.setDependencyCheck(root.getAttribute(DEFAULT_DEPENDENCY_CHECK_ATTRIBUTE)); //设置 default-autowire-candidates if (root.hasAttribute(DEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE)) { defaults.setAutowireCandidates(root.getAttribute(DEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE)); } else if (parentDefaults != null) { defaults.setAutowireCandidates(parentDefaults.getAutowireCandidates()); } //设置 default-init-method if (root.hasAttribute(DEFAULT_INIT_METHOD_ATTRIBUTE)) { defaults.setInitMethod(root.getAttribute(DEFAULT_INIT_METHOD_ATTRIBUTE)); } else if (parentDefaults != null) { defaults.setInitMethod(parentDefaults.getInitMethod()); } //设置 default-destroy-method if (root.hasAttribute(DEFAULT_DESTROY_METHOD_ATTRIBUTE)) { defaults.setDestroyMethod(root.getAttribute(DEFAULT_DESTROY_METHOD_ATTRIBUTE)); } else if (parentDefaults != null) { defaults.setDestroyMethod(parentDefaults.getDestroyMethod()); } //设置此DocumentDefaultsDefinition的元数据源 defaults.setSource(this.readerContext.extractSource(root)); }
一个beans的图示spring
委托模式石锤了!这里把root交给委托类delegate来处理,委托类delegate经过XmlReaderContext持有当前的XmlBeanDefinitionReader、命名空间解析器、原始资源、事件分发器等,又直接持有环境的引用,而XmlBeanDefinitionReader又有BeanDefinitionRegistry的引用,能够说集万千宠爱于一身,因此能力很是强大。我不得不画个图来表示一下敬意!数组
这里解析是的app
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { //判断root的xlmns是否是默认的名称空间,即"http://www.springframework.org/schema/beans" //这里是的 if (delegate.isDefaultNamespace(root)) { //获取所有子节点并遍历 NodeList nl = root.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); //若是节点是Element的话,这里主要是为了去除xml中无用的Text空节点 //好比:__<A>a</A>__<B></B>__ 是有5个Node的 //分别是: //1. 空白Text节点 //2. <A>节点 //3. 空白Text节点 //4. <B>节点 //5. 空白Text节点 if (node instanceof Element) { Element ele = (Element) node; if (delegate.isDefaultNamespace(ele)) { //解析有效节点,处理不一样的标签 import bean alias beans parseDefaultElement(ele, delegate); } else { delegate.parseCustomElement(ele); } } } } else { delegate.parseCustomElement(root); } }
处理import 、alias、bean、beans 这四种标签其中最复杂的就是 beans 标签,他会致使程序递归到DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions方法,而后重复上面的全部步骤,有兴趣的同窗能够在< beans> 标签中嵌入一个< beans>,来研究下Spring是如何处理递归的。我这里就再也不深刻讨论了。ide
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { //处理 import 标签 if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { importBeanDefinitionResource(ele); } // //处理 alias 标签 else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { processAliasRegistration(ele); } //处理 bean 标签 else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { processBeanDefinition(ele, delegate); } //处理 beans 标签 else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { // recurse doRegisterBeanDefinitions(ele); } }
处理bean标签,先解析默认命名空间中的属性、和子标签而后处理非默认命名空间的标签函数
接着注册BeanDefinitionpost
最后发送一个BeanDefinition注册事件ui
/** * Process the given bean element, parsing the bean definition * and registering it with the registry. */ protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { //解析ele成BeanDefinition,并放入到BeanDefinitionHolder中 BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); //若是bdHolder解析成功了就进行 if (bdHolder != null) { //解析非默认命名空间的属性 //好比 http://www.springframework.org/schema/c 之类的标签 //对应的解析器也是就在springs.handlers文件中配置的,好比*/c的是org.springframework.beans.factory.xml.SimpleConstructorNamespaceHandler bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); try { //向IOC中注册该BeanDefiniton!!! BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); } catch (BeanDefinitionStoreException ex) { getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, ex); } //最后发送一个BeanDefinition注册事件 getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); } }
//调用parseBeanDefinitionElement public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) { return parseBeanDefinitionElement(ele, null); } //实际将Element解析成Beanfinition的方法 public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) { //获取id属性 String id = ele.getAttribute(ID_ATTRIBUTE); //获取name属性 String nameAttr = ele.getAttribute(NAME_ATTRIBUTE); //别名list List<String> aliases = new ArrayList<String>(); //若是name属性值不为空,按照 ,; 符号切分name,切分红一个name属性,并放入到aliases中 //这里看出bean的定义,能够定义多个name值,只要经过逗号或者分号分隔便可。 if (StringUtils.hasLength(nameAttr)) { String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS); aliases.addAll(Arrays.asList(nameArr)); } //把beanName设置成id, String beanName = id; //若是没有配置id,就把name中配置的第一个值做为beanName if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) { beanName = aliases.remove(0); if (logger.isDebugEnabled()) { logger.debug("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases"); } } //若是传入的containingBean为null,就检验beanName和aliases是否是已经被占用了, //占用了就抛出一个异常BeanDefinitionParsingException, //这里传入的containingBean就是null,因此必定要通过里面检查 if (containingBean == null) { checkNameUniqueness(beanName, aliases, ele); } //把ele解析 beanDefinition, //其中此处的 beanDefinition的类型是GenericBeanDefinition AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean); if (beanDefinition != null) { //若是beanName没有的话,就使用BeanDefinitionReaderUtils.generateBeanName生成一个名字 if (!StringUtils.hasText(beanName)) { try { if (containingBean != null) { beanName = BeanDefinitionReaderUtils.generateBeanName( beanDefinition, this.readerContext.getRegistry(), true); } else { beanName = this.readerContext.generateBeanName(beanDefinition); // Register an alias for the plain bean class name, if still possible, // if the generator returned the class name plus a suffix. // This is expected for Spring 1.2/2.0 backwards compatibility. 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); // 用一个BeanDefinitionHolder ,把beanDefinition, beanName, aliasesArray封装在一块儿而后返回 return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray); } return null; }
//检查benaName、aliases是否被以前的bean占用 protected void checkNameUniqueness(String beanName, List<String> aliases, Element beanElement) { String foundName = null; //判断beanName是否被使用 if (StringUtils.hasText(beanName) && this.usedNames.contains(beanName)) { foundName = beanName; } //判断是否aliases中有被占用的 if (foundName == null) { foundName = (String) CollectionUtils.findFirstMatch(this.usedNames, aliases); } //若是找到了占用,就抛出异常 if (foundName != null) { error("Bean name '" + foundName + "' is already used in this <beans> element", beanElement); } //若是没有发现占用,就把beanName和aliaes所有放入到usedNames中 this.usedNames.add(beanName); this.usedNames.addAll(aliases); }
解析Bean中几乎全部的属性和一些配置的子标签,一个示例Bean标签的配置如图
//Element解析成AbstractBeanDefinition public AbstractBeanDefinition parseBeanDefinitionElement( Element ele, String beanName, BeanDefinition containingBean) { //把beanName压入到栈parseState中 this.parseState.push(new BeanEntry(beanName)); String className = null; //获取class属性值,放入到className中 if (ele.hasAttribute(CLASS_ATTRIBUTE)) { className = ele.getAttribute(CLASS_ATTRIBUTE).trim(); } try { //若是有parent属性,设置到parent中 String parent = null; if (ele.hasAttribute(PARENT_ATTRIBUTE)) { parent = ele.getAttribute(PARENT_ATTRIBUTE); } //建立一个AbstractBeanDefinition,类型是GenericBeanDefinition AbstractBeanDefinition bd = createBeanDefinition(className, parent); //解析ele的属性,并设置到BeanDefinition中 parseBeanDefinitionAttributes(ele, beanName, containingBean, bd); //若是此bean标签有子标签description的话,就把description中的值设置到bd中 // <description>message</description> bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT)); //解析<meta>子标签 // <meta key="bk" value="bv"/> parseMetaElements(ele, bd); //解析<lookup-method> 子标签,把配置的lookup-method放入到bd的methodOverrides中 // <lookup-method name="getAdmin" bean="parent"/> parseLookupOverrideSubElements(ele, bd.getMethodOverrides()); //解析 replaced-method 标签 // <replaced-method name="toString" replacer="methodPlacer"/> parseReplacedMethodSubElements(ele, bd.getMethodOverrides()); //解析 构造函数标签 <constructor-arg> // <constructor-arg name="name" value="nn"/> parseConstructorArgElements(ele, bd); //解析 属性标签 <property> parsePropertyElements(ele, bd); //解析 <qualifier> 标签 parseQualifierElements(ele, bd); bd.setResource(this.readerContext.getResource()); bd.setSource(extractSource(ele)); return bd; } catch (ClassNotFoundException ex) { error("Bean class [" + className + "] not found", ele, ex); } catch (NoClassDefFoundError err) { error("Class that bean class [" + className + "] depends on not found", ele, err); } catch (Throwable ex) { error("Unexpected failure during bean definition parsing", ele, ex); } finally { this.parseState.pop(); } return null; }
//利用className和parentName建立一个BeanDefinition protected AbstractBeanDefinition createBeanDefinition(String className, String parentName) throws ClassNotFoundException { return BeanDefinitionReaderUtils.createBeanDefinition( parentName, className, this.readerContext.getBeanClassLoader()); } //BeanDefinitionReaderUtils.createBeanDefinition方法建立的BeanDefinition的类型是GenericBeanDefinition public static AbstractBeanDefinition createBeanDefinition( String parentName, String className, ClassLoader classLoader) throws ClassNotFoundException { //建立一个GenericBeanDefinition,设置ParentName, GenericBeanDefinition bd = new GenericBeanDefinition(); bd.setParentName(parentName); //若是能够className和classLoader都有值的话,就把类Class加载出来,并设置到bd中 //若是classLoder为空的话,就只设置一个className if (className != null) { if (classLoader != null) { // bd.setBeanClass(ClassUtils.forName(className, classLoader)); } else { bd.setBeanClassName(className); } } return bd; }
几乎设置了一个BeanDefinition须要的所有属性
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName, BeanDefinition containingBean, AbstractBeanDefinition bd) { //解析spring2.x中的scope属性 //解析Spring1.x中的singleton属性 if (ele.hasAttribute(SCOPE_ATTRIBUTE)) { // Spring 2.x "scope" attribute bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE)); if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) { error("Specify either 'scope' or 'singleton', not both", ele); } } else if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) { // Spring 1.x "singleton" attribute bd.setScope(TRUE_VALUE.equals(ele.getAttribute(SINGLETON_ATTRIBUTE)) ? BeanDefinition.SCOPE_SINGLETON : BeanDefinition.SCOPE_PROTOTYPE); } else if (containingBean != null) { // Take default from containing bean in case of an inner bean definition. bd.setScope(containingBean.getScope()); } //设置bd的 abstract 属性 if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) { bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE))); } //设置bd的 lazy-init 属性 String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE); if (DEFAULT_VALUE.equals(lazyInit)) { lazyInit = this.defaults.getLazyInit(); } bd.setLazyInit(TRUE_VALUE.equals(lazyInit)); //设置bd的 autowire 属性 String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE); bd.setAutowireMode(getAutowireMode(autowire)); //设置bd的 dependency-check 属性 String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE); bd.setDependencyCheck(getDependencyCheck(dependencyCheck)); //设置bd的 depends-on 属性 if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) { String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE); bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS)); } //设置bd的 autowire-candidate 属性 String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE); if ("".equals(autowireCandidate) || DEFAULT_VALUE.equals(autowireCandidate)) { String candidatePattern = this.defaults.getAutowireCandidates(); if (candidatePattern != null) { String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern); bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName)); } } else { bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate)); } //设置bd的 primary 属性 if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) { bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE))); } //设置bd的 init-method 属性 if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) { String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE); if (!"".equals(initMethodName)) { bd.setInitMethodName(initMethodName); } } else { if (this.defaults.getInitMethod() != null) { bd.setInitMethodName(this.defaults.getInitMethod()); bd.setEnforceInitMethod(false); } } //设置bd的 destroy-method 属性 if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) { String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE); if (!"".equals(destroyMethodName)) { bd.setDestroyMethodName(destroyMethodName); } } else { if (this.defaults.getDestroyMethod() != null) { bd.setDestroyMethodName(this.defaults.getDestroyMethod()); bd.setEnforceDestroyMethod(false); } } //设置bd的 factory-method 属性 if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) { bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE)); } //设置bd的 factory-bean 属性 if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) { bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE)); } return bd; }
BeanDefinition的继承关系图,能够看出GenericBeanDefinition的位置this
写的有点太多了,还有import标签和 alias标签的解析内容,我放置《BeanDefinition注册-下篇》中一块儿讲解。下篇中也会补充一些此文中关于注册BeanDefintion的细节内容。