spring容器标签解析之meta

上节我们在spring容器之Bean标签的解析中知道了我们最核心的bean标签的解析过程,在BeanDefinitionParserDelegate#parseBeanDefinitionElement()方法中完成,其中也有相关子元素的解析过程,如:meta标签以及lookup-method等标签的解析过程,这也是我们上篇遗留的问题,接下来我们看.

Meta标签解析

对于meta标签可能很多人都不清楚,这里简单的说一下:


  
  
  

在这段代码中,我们可以发现作为了bean标签的字标签来使用,我在配置中写的key是当需要bean的meta信息时,可以通过beanDefinition的getAttribute(key)方法进行获取
接下来我们来看spring是解析字标签meta的过程:

//解析子标签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);
        //从所有子元素中拿到meta元素
        if (isCandidateElement(node) && nodeNameEquals(node, META_ELEMENT)) {
            Element metaElement = (Element) node;
            //获取meta的key和value
            String key = metaElement.getAttribute(KEY_ATTRIBUTE);
            String value = metaElement.getAttribute(VALUE_ATTRIBUTE);
            //通过获取到的key和value来构建BeanMetadataAttribute属性
            BeanMetadataAttribute attribute = new BeanMetadataAttribute(key, value);
            //封装source属性
            attribute.setSource(extractSource(metaElement));
            //保存属性
            attributeAccessor.addMetadataAttribute(attribute);
        }
    }
}

上述代码就是字标签meta的解析过程,简单的总结下:

  • 首先是通过传入的参数ele,获取所有的子元素
NodeList nl = ele.getChildNodes();
  • 接下来遍历所有的子元素,拿到我们想要的meta元素,于此同时获取key和value
public static final String META_ELEMENT = "meta";
Element metaElement = (Element) node;
//获取meta的key和value
String key = metaElement.getAttribute(KEY_ATTRIBUTE);
String value = metaElement.getAttribute(VALUE_ATTRIBUTE);
  • 通过获取到的key和value来构建BeanMetadataAttribute属性
BeanMetadataAttribute attribute = new BeanMetadataAttribute(key, value);

这里有一个关于BeanMetadataAttribute的属性类,我们来看一下:

BeanMetadataAttribute

大概来说,BeanMetadataAttribute是表示bean元数据定义的信息,以key-value的形式存在,实质该属性属于beanDefinition的一部分,接着看它的继承实现关系和一些常用的方法:

BeanMetadataAttribute.png
public class BeanMetadataAttribute implements BeanMetadataElement {

private final String name; //key

@Nullable
private final Object value;

@Nullable
private Object source; //元数据的配置文件资源


/**
 * Create a new AttributeValue instance.
 * @param name the name of the attribute (never {@code null})
 * @param value the value of the attribute (possibly before type conversion)
 */
public BeanMetadataAttribute(String name, @Nullable Object value) {
    Assert.notNull(name, "Name must not be null");
    this.name = name;
    this.value = value;
}


/**
 * Return the name of the attribute.
 */
public String getName() {
    return this.name;
}

/**
 * Return the value of the attribute.
 */
@Nullable
public Object getValue() {
    return this.value;
}

/**
 * Set the configuration source {@code Object} for this metadata element.
 * 

The exact type of the object will depend on the configuration mechanism used. */ public void setSource(@Nullable Object source) { this.source = source; } @Override @Nullable public Object getSource() { return this.source; }

我们从它的家族图可以看出,实现了BeanMetadataElement接口,而该接口中只有一个获取元数据配置资源的方法,对于它本身来说,方法简单这里就不说了,接着看

  • 属性的封装
attributeAccessor.addMetadataAttribute(attribute);

封装过程中调用了BeanMetadataAttributeAccessor#addMetadataAttribute方法,这里首先看一下BeanMetadataAttributeAccessor类的作用

BeanMetadataAttributeAccessor

该类的主要的作用是将属性进行封装成BeanMetadataAttribute对象,来看一下的它的继承关系

BeanMetadataAttributeAccessor.png

有图可以看出BeanMetadataAttributeAccessor类直接继承AttributeAccessorSupport且实现了BeanMetadataElement接口,直接看代码:

public class BeanMetadataAttributeAccessor extends AttributeAccessorSupport implements BeanMetadataElement {

@Nullable
private Object source;


/**
 * Set the configuration source {@code Object} for this metadata element.
 * 

The exact type of the object will depend on the configuration mechanism used. */ //封装source public void setSource(@Nullable Object source) { this.source = source; } @Override @Nullable public Object getSource() { return this.source; } /** * Add the given BeanMetadataAttribute to this accessor's set of attributes. * @param attribute the BeanMetadataAttribute object to register */ //保存 public void addMetadataAttribute(BeanMetadataAttribute attribute) { super.setAttribute(attribute.getName(), attribute); } /** * Look up the given BeanMetadataAttribute in this accessor's set of attributes. * @param name the name of the attribute * @return the corresponding BeanMetadataAttribute object, * or {@code null} if no such attribute defined */ @Nullable public BeanMetadataAttribute getMetadataAttribute(String name) { return (BeanMetadataAttribute) super.getAttribute(name); } @Override public void setAttribute(String name, @Nullable Object value) { super.setAttribute(name, new BeanMetadataAttribute(name, value)); } @Override @Nullable public Object getAttribute(String name) { BeanMetadataAttribute attribute = (BeanMetadataAttribute) super.getAttribute(name); return (attribute != null ? attribute.getValue() : null); } @Override @Nullable public Object removeAttribute(String name) { BeanMetadataAttribute attribute = (BeanMetadataAttribute) super.removeAttribute(name); return (attribute != null ? attribute.getValue() : null); } }

这就是BeanMetadataAttributeAccessor类的方法,以上关于字标签meta整个的解析过程,后续来说其他的......

你可能感兴趣的:(spring容器标签解析之meta)