上文说到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));
}
设置了命名空间解析器为DefaultNamespaceHandlerResolver
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());
}
比如对于xmlns为http://www.springframework.org/schema/c的命名空间的处理器为org.springframework.beans.factory.xml.SimpleConstructorNamespaceHandler
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));
}
委托模式石锤了!
这里把root交给委托类delegate来处理,委托类delegate通过XmlReaderContext持有当前的XmlBeanDefinitionReader、命名空间解析器、原始资源、事件分发器等,又直接持有环境的引用,而XmlBeanDefinitionReader又有BeanDefinitionRegistry的引用,可以说集万千宠爱于一身,所以能力非常强大。我不得不画个图来表示一下敬意!
这里解析是的
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);
}
}
其中最复杂的就是 beans 标签,他会导致程序递归到DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions方法,然后重复上面的所有步骤,有兴趣的同学可以在< beans> 标签中嵌入一个< beans>,来研究下Spring是如何处理递归的。我这里就不再深入讨论了。
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标签,先解析默认命名空间中的属性、和子标签
然后处理非默认命名空间的标签
接着注册BeanDefinition
最后发送一个BeanDefinition注册事件
/**
* 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);
}
//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的位置
下篇中也会补充一些此文中关于注册BeanDefintion的细节内容。