GenericBeanDefinition的关系结构图
GenericBeanDefinition用于承载解析出来的Bean信息
DefaultBeanDefinitionParserDelegate
parseBeanDefinitionElement:解析bean标签,并以BeanDefinitionHolder对象返回
@Nullable
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
return parseBeanDefinitionElement(ele, null);
}
parseBeanDefinitionElement:
1、提取元素中的id和name属性
2、进一步解析其他所有属性,并封装到GenericBeanDefinition中
3、如果没有beanName则使用默认规则生成一个
4、将获取的信息封装到GenericBeanDefinition中返回
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
//获取id和name
String id = ele.getAttribute(ID_ATTRIBUTE);
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
//别名集合,以,或者;分割所有name,存进aliases
List<String> aliases = new ArrayList<>();
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
aliases.addAll(Arrays.asList(nameArr));
}
//bean名字默认为id,若没有id则使用name值中的第一个值
String beanName = id;
if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
beanName = aliases.remove(0);
if (logger.isTraceEnabled()) {}
}
待定-------------------------------------------------
if (containingBean == null) {
checkNameUniqueness(beanName, aliases, ele);
}
//解析其他属性和子标签,并将其与AbstractBeanDefinition的属性值对应
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
//
if (beanDefinition != null) {
if (!StringUtils.hasText(beanName)) {
try {
if (containingBean != null) {
beanName = BeanDefinitionReaderUtils.generateBeanName(
beanDefinition, this.readerContext.getRegistry(), true);
}
else {
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.isTraceEnabled()) {}
}
catch (Exception ex) {
error(ex.getMessage(), ele);return null;
}
}
String[] aliasesArray = StringUtils.toStringArray(aliases);
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
}
return null;
}
parseBeanDefinitionElement
解析标签所有子标签和属性,将属性值放进AbstractBeanDefinition 返回
public AbstractBeanDefinition parseBeanDefinitionElement(
Element ele, String beanName, @Nullable BeanDefinition containingBean) {
//ParseState有一个属性ArrayDeque<Entry> state;Entry说白了就是给String类型包了一层,然后叫BeanEntry
this.parseState.push(new BeanEntry(beanName));
//获取className和parent
String className = null;
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
}
String parent = null;
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
try {
//见内部代码2.1:设置了beanClass和parentName属性,对于beanClass,若readerContext的classLoader不为空,则直接将Class实例加载给beanClass,否则直接设置一个className,即类的全限定名
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
//见内部代码2.2;解析标签的所有属性;该方法返回了bd,但bd也作为参数传进去了,所以没使用返回值
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
//查看该bean里有无子标签<description>,有则将其内容取出,设置
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
//见内部代码2.3:
parseMetaElements(ele, bd);
//见内部代码2.4;
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
//见内部代码2.5;
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
//见内部代码2.6:
parseConstructorArgElements(ele, bd);
parsePropertyElements(ele, bd);
parseQualifierElements(ele, bd);
bd.setResource(this.readerContext.getResource());
bd.setSource(extractSource(ele));
return bd;
}
catch (ClassNotFoundException ex) {}
finally {
this.parseState.pop();
}
return null;
}
内部代码2.1:创建并初始化AbstractBeanDefinition
设置parentName和beanClass属性,使用Object beanClass属性接收String类型的className或者Class类型的已加载的类
protected AbstractBeanDefinition createBeanDefinition(@Nullable String className, @Nullable String parentName)
throws ClassNotFoundException {
return BeanDefinitionReaderUtils.createBeanDefinition(
parentName, className, this.readerContext.getBeanClassLoader());
}
---------BeanDefinitionReaderUtils----------------------
public static AbstractBeanDefinition createBeanDefinition(
@Nullable String parentName, @Nullable String className, @Nullable ClassLoader classLoader) throws ClassNotFoundException {
//该构造器继续调用super,最终给2个属性赋值null------》等于什么都没做
GenericBeanDefinition bd = new GenericBeanDefinition();
//设置parent属性
bd.setParentName(parentName);
//使用Object beanClass属性接收String类型的className或者Class类型的已加载的类
if (className != null) {
if (classLoader != null) {
bd.setBeanClass(ClassUtils.forName(className, classLoader));
}
else {
bd.setBeanClassName(className);
}
}
return bd;
}
内部代码2.2:parseBeanDefinitionAttributes:解析标签的所有属性
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
@Nullable BeanDefinition containingBean, AbstractBeanDefinition bd) {
}
内部代码2.3:parseMetaElements:解析子元素meta
首先先看下meta的作用:可以使用BeanDifinition的getAttribute(key)方法得到value值
<bean id="myBean" class="com.example.pojo.MyBean" init-method=" ">
<meta key="myBeanMetaKey" value="myBeanMetaValue" />
</bean>
解析meta属性:
public void parseMetaElements(Element ele, BeanMetadataAttributeAccessor attributeAccessor) {
NodeList nl = ele.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (isCandidateElement(node) && nodeNameEquals(node, META_ELEMENT)) {
Element metaElement = (Element) node;
String key = metaElement.getAttribute(KEY_ATTRIBUTE);
String value = metaElement.getAttribute(VALUE_ATTRIBUTE);
BeanMetadataAttribute attribute = new BeanMetadataAttribute(key, value);
attribute.setSource(extractSource(metaElement));
attributeAccessor.addMetadataAttribute(attribute);
}
}
}
内部代码2.4:parseLookupOverrideSubElements
获取<bean>下的<lookup-method>
<lookup-method\ name=“methodName” bean=“beanRef” />
:可以给没有实现类的抽象方法指定返回的实例对象
public void parseLookupOverrideSubElements(Element beanEle, MethodOverrides overrides) {
NodeList nl = beanEle.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (isCandidateElement(node) && nodeNameEquals(node, LOOKUP_METHOD_ELEMENT)) {
Element ele = (Element) node;
String methodName = ele.getAttribute(NAME_ATTRIBUTE);
String beanRef = ele.getAttribute(BEAN_ELEMENT);
LookupOverride override = new LookupOverride(methodName, beanRef);
override.setSource(extractSource(ele));
overrides.addOverride(override);
}
}
}
内部代码2.6:解析ConstructorArg标签
遍历该标签下所有ConstructorArg标签,挨个解析
1、parseConstructorArgElements
//对每个constructor-arg标签进行解析
public void parseConstructorArgElements(Element beanEle, BeanDefinition bd) {
NodeList nl = beanEle.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (isCandidateElement(node) && nodeNameEquals(node, CONSTRUCTOR_ARG_ELEMENT)) {
parseConstructorArgElement((Element) node, bd);
}
}
}
2、parseConstructorArgElement
1、获取index,type,name属性
2.1、如果配置了index属性,则
- 解析constructor-arg子标签
- 使用ConstructorArgumentValues.ValueHolder封装解析结果
- 将type、name和index封装进ConstructorArgumentValues.ValueHolder并添加至ConstructorArgumentValues的indexedArgumentValues属性中
private final Map<Integer, ValueHolder> indexedArgumentValues = new LinkedHashMap<>();
2.2、若没有配置index属性
- 解析constructor-arg子标签
- 使用ConstructorArgumentValues.ValueHolder封装解析结果
- 将type、name和index封装进ConstructorArgumentValues.ValueHolder并添加至ConstructorArgumentValues的 genericArgumentValues属性中
private final List<ValueHolder> genericArgumentValues = new ArrayList<>();
//
public void parseConstructorArgElement(Element ele, BeanDefinition bd) {
String indexAttr = ele.getAttribute(INDEX_ATTRIBUTE);
String typeAttr = ele.getAttribute(TYPE_ATTRIBUTE);
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
//若存在index属性,
if (StringUtils.hasLength(indexAttr)) {
try {
int index = Integer.parseInt(indexAttr);
if (index < 0) {
error("'index' cannot be lower than 0", ele);
}
else {
try {
this.parseState.push(new ConstructorArgumentEntry(index));
Object value = parsePropertyValue(ele, bd, null);
ConstructorArgumentValues.ValueHolder valueHolder = new ConstructorArgumentValues.ValueHolder(value);
if (StringUtils.hasLength(typeAttr)) {
valueHolder.setType(typeAttr);
}
if (StringUtils.hasLength(nameAttr)) {
valueHolder.setName(nameAttr);
}
valueHolder.setSource(extractSource(ele));
if (bd.getConstructorArgumentValues().hasIndexedArgumentValue(index)) {
error("Ambiguous constructor-arg entries for index " + index, ele);
}
else {
bd.getConstructorArgumentValues().addIndexedArgumentValue(index, valueHolder);
}
}
finally {
this.parseState.pop();
}
}
}
catch (NumberFormatException ex) {
error("Attribute 'index' of tag 'constructor-arg' must be an integer", ele);
}
}
else {
try {
this.parseState.push(new ConstructorArgumentEntry());
Object value = parsePropertyValue(ele, bd, null);
ConstructorArgumentValues.ValueHolder valueHolder = new ConstructorArgumentValues.ValueHolder(value);
if (StringUtils.hasLength(typeAttr)) {
valueHolder.setType(typeAttr);
}
if (StringUtils.hasLength(nameAttr)) {
valueHolder.setName(nameAttr);
}
valueHolder.setSource(extractSource(ele));
bd.getConstructorArgumentValues().addGenericArgumentValue(valueHolder);
}
finally {
this.parseState.pop();
}
}
}
3、parsePropertyValue
解析构造器标签值
@Nullable
public Object parsePropertyValue(Element ele, BeanDefinition bd, @Nullable String propertyName) {
String elementName = (propertyName != null ?
"<property> element for property '" + propertyName + "'" :
"<constructor-arg> element");
// 获取该标签的所有子标签
NodeList nl = ele.getChildNodes();
//子标签中除了<meta>和<description>,其余的只能存在一个,否则报错,并将仅有一个赋值给subElement
Element subElement = null;
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element && !nodeNameEquals(node, DESCRIPTION_ELEMENT) &&
!nodeNameEquals(node, META_ELEMENT)) {
// Child element is what we're looking for.
if (subElement != null) {
error(elementName + " must not contain more than one sub-element", ele);
}
else {
subElement = (Element) node;
}
}
}
//<construct-arg>标签的ref和value属性同时存在,或者二者存一并且subElement不为空,则报错
boolean hasRefAttribute = ele.hasAttribute(REF_ATTRIBUTE);
boolean hasValueAttribute = ele.hasAttribute(VALUE_ATTRIBUTE);
if ((hasRefAttribute && hasValueAttribute) ||
((hasRefAttribute || hasValueAttribute) && subElement != null)) {
error(elementName +
" is only allowed to contain either 'ref' attribute OR 'value' attribute OR sub-element", ele);
}
//ref的值若存在,则保存在RuntimeBeanReference实例中并标明来源,返回
if (hasRefAttribute) {
String refName = ele.getAttribute(REF_ATTRIBUTE);
if (!StringUtils.hasText(refName)) {
error(elementName + " contains empty 'ref' attribute", ele);
}
RuntimeBeanReference ref = new RuntimeBeanReference(refName);
//标明来源
ref.setSource(extractSource(ele));
return ref;
}
//同理,value值和ref值处理类似,只不过存在了TypedStringValue实例
else if (hasValueAttribute) {
TypedStringValue valueHolder = new TypedStringValue(ele.getAttribute(VALUE_ATTRIBUTE));
//标明来源
valueHolder.setSource(extractSource(ele));
return valueHolder;
}
//对子标签进行解析
else if (subElement != null) {
return parsePropertySubElement(subElement, bd);
}
else {
// Neither child element nor "ref" or "value" attribute found.
error(elementName + " must specify a ref or value", ele);
return null;
}
}
其他方法也是类似,就不逐一分析了