对dom树的解析封装成应有的数据结构--BeanDefinitionParserDelegate

拒绝就业的后果是什么?如果在上山下乡的时候,必定被居委会大妈每天烦扰了,然后禁不住死缠烂打就上山下乡了,这个时代是相对幸运的,至少政策没有那么严苛,那么我今天就进入最喜欢的一个类的解析了,所有解释型的语言都有一个队DOM树的PASER,Spring中的PASER,是这个类:BeanDefinitionParserDelegate。

public static final String BEANS_NAMESPACE_URI = "http://www.springframework.org/schema/beans";
 public static final String MULTI_VALUE_ATTRIBUTE_DELIMITERS = ",; ";

第一个属性石Spring框架的命名空间URI,http://www.springframework.org/schema/beans。点击开网址,会看到一些关于Spring的xsd文件,是一种解析规则,看来服务器还是要和Spring的官方服务器进行对话的。

第二个属性定义了一个Value属性的分隔符。

/** @deprecated as of Spring 3.1 in favor of {@link #MULTI_VALUE_ATTRIBUTE_DELIMITERS} */
 public static final String BEAN_NAME_DELIMITERS = MULTI_VALUE_ATTRIBUTE_DELIMITERS;

被弃用的属性。

/**
  * Value of a T/F attribute that represents true.
  * Anything else represents false. Case seNsItive.
  */
 public static final String TRUE_VALUE = "true";
 public static final String FALSE_VALUE = "false";
 public static final String DEFAULT_VALUE = "default";
 public static final String DESCRIPTION_ELEMENT = "description";
 public static final String AUTOWIRE_NO_VALUE = "no";
 public static final String AUTOWIRE_BY_NAME_VALUE = "byName";
 public static final String AUTOWIRE_BY_TYPE_VALUE = "byType";
 public static final String AUTOWIRE_CONSTRUCTOR_VALUE = "constructor";
 public static final String AUTOWIRE_AUTODETECT_VALUE = "autodetect";
 public static final String DEPENDENCY_CHECK_ALL_ATTRIBUTE_VALUE = "all";
 public static final String DEPENDENCY_CHECK_SIMPLE_ATTRIBUTE_VALUE = "simple";
 public static final String DEPENDENCY_CHECK_OBJECTS_ATTRIBUTE_VALUE = "objects";
 public static final String NAME_ATTRIBUTE = "name";
 public static final String BEAN_ELEMENT = "bean";
 public static final String META_ELEMENT = "meta";
 public static final String ID_ATTRIBUTE = "id";
 public static final String PARENT_ATTRIBUTE = "parent";
 public static final String CLASS_ATTRIBUTE = "class";
 public static final String ABSTRACT_ATTRIBUTE = "abstract";
 public static final String SCOPE_ATTRIBUTE = "scope";
 public static final String SINGLETON_ATTRIBUTE = "singleton";
 public static final String LAZY_INIT_ATTRIBUTE = "lazy-init";
 public static final String AUTOWIRE_ATTRIBUTE = "autowire";
 public static final String AUTOWIRE_CANDIDATE_ATTRIBUTE = "autowire-candidate";
 public static final String PRIMARY_ATTRIBUTE = "primary";
 public static final String DEPENDENCY_CHECK_ATTRIBUTE = "dependency-check";
 public static final String DEPENDS_ON_ATTRIBUTE = "depends-on";
 public static final String INIT_METHOD_ATTRIBUTE = "init-method";
 public static final String DESTROY_METHOD_ATTRIBUTE = "destroy-method";
 public static final String FACTORY_METHOD_ATTRIBUTE = "factory-method";
 public static final String FACTORY_BEAN_ATTRIBUTE = "factory-bean";
 public static final String CONSTRUCTOR_ARG_ELEMENT = "constructor-arg";
 public static final String INDEX_ATTRIBUTE = "index";
 public static final String TYPE_ATTRIBUTE = "type";
 public static final String VALUE_TYPE_ATTRIBUTE = "value-type";
 public static final String KEY_TYPE_ATTRIBUTE = "key-type";
 public static final String PROPERTY_ELEMENT = "property";
 public static final String REF_ATTRIBUTE = "ref";
 public static final String VALUE_ATTRIBUTE = "value";
 public static final String LOOKUP_METHOD_ELEMENT = "lookup-method";
 public static final String REPLACED_METHOD_ELEMENT = "replaced-method";
 public static final String REPLACER_ATTRIBUTE = "replacer";
 public static final String ARG_TYPE_ELEMENT = "arg-type";
 public static final String ARG_TYPE_MATCH_ATTRIBUTE = "match";
 public static final String REF_ELEMENT = "ref";
 public static final String IDREF_ELEMENT = "idref";
 public static final String BEAN_REF_ATTRIBUTE = "bean";
 public static final String LOCAL_REF_ATTRIBUTE = "local";
 public static final String PARENT_REF_ATTRIBUTE = "parent";
 public static final String VALUE_ELEMENT = "value";
 public static final String NULL_ELEMENT = "null";
 public static final String ARRAY_ELEMENT = "array";
 public static final String LIST_ELEMENT = "list";
 public static final String SET_ELEMENT = "set";
 public static final String MAP_ELEMENT = "map";
 public static final String ENTRY_ELEMENT = "entry";
 public static final String KEY_ELEMENT = "key";
 public static final String KEY_ATTRIBUTE = "key";
 public static final String KEY_REF_ATTRIBUTE = "key-ref";
 public static final String VALUE_REF_ATTRIBUTE = "value-ref";
 public static final String PROPS_ELEMENT = "props";
 public static final String PROP_ELEMENT = "prop";
 public static final String MERGE_ATTRIBUTE = "merge";
 public static final String QUALIFIER_ELEMENT = "qualifier";
 public static final String QUALIFIER_ATTRIBUTE_ELEMENT = "attribute";
 public static final String DEFAULT_LAZY_INIT_ATTRIBUTE = "default-lazy-init";
 public static final String DEFAULT_MERGE_ATTRIBUTE = "default-merge";
 public static final String DEFAULT_AUTOWIRE_ATTRIBUTE = "default-autowire";
 public static final String DEFAULT_DEPENDENCY_CHECK_ATTRIBUTE = "default-dependency-check";
 public static final String DEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE = "default-autowire-candidates";
 public static final String DEFAULT_INIT_METHOD_ATTRIBUTE = "default-init-method";
 public static final String DEFAULT_DESTROY_METHOD_ATTRIBUTE = "default-destroy-method";

终于见面了,这些在xml中配置的属性。

protected final Log logger = LogFactory.getLog(getClass());
 private final XmlReaderContext readerContext;
 private final DocumentDefaultsDefinition defaults = new DocumentDefaultsDefinition();
 private final ParseState parseState = new ParseState();
 private Environment environment;

日志,XMLrEADERcONTEXT,DocumentDefaultsDefinition,ParseState,Environment。

/**
  * Stores all used bean names so we can enforce uniqueness on a per
  * beans-element basis. Duplicate bean ids/names may not exist within the
  * same level of beans element nesting, but may be duplicated across levels.
  */
 private final Set<String> usedNames = new HashSet<String>();

让属性名字唯一。

/**
  * Create a new BeanDefinitionParserDelegate associated with the
  * supplied {@link XmlReaderContext} and {@link Environment}.
  */
 public BeanDefinitionParserDelegate(XmlReaderContext readerContext, Environment environment) {
  Assert.notNull(readerContext, "XmlReaderContext must not be null");
  Assert.notNull(readerContext, "Environment must not be null");
  this.readerContext = readerContext;
  this.environment = environment;
 }

初始化。

 /**
  * Create a new BeanDefinitionParserDelegate associated with the
  * supplied {@link XmlReaderContext} and a new {@link StandardEnvironment}.
  * @deprecated since Spring 3.1 in favor of
  * {@link #BeanDefinitionParserDelegate(XmlReaderContext, Environment)}
  */
 @Deprecated
 public BeanDefinitionParserDelegate(XmlReaderContext readerContext) {
  this(readerContext, new StandardEnvironment());
 }

默认的环境初始化。

 /**
  * Get the {@link XmlReaderContext} associated with this helper instance.
  */
 public final XmlReaderContext getReaderContext() {
  return this.readerContext;
 }
 /**
  * Get the {@link Environment} associated with this helper instance.
  */
 public final Environment getEnvironment() {
  return this.environment;
 }

get到。

/**
  * Invoke the {@link org.springframework.beans.factory.parsing.SourceExtractor} to pull the
  * source metadata from the supplied {@link Element}.
  */
 protected Object extractSource(Element ele) {
  return this.readerContext.extractSource(ele);
 }

从封装好的Element中提取Source。

/**
  * Report an error with the given message for the given source element.
  */
 protected void error(String message, Node source) {
  this.readerContext.error(message, source, this.parseState.snapshot());
 }
 /**
  * Report an error with the given message for the given source element.
  */
 protected void error(String message, Element source) {
  this.readerContext.error(message, source, this.parseState.snapshot());
 }
 /**
  * Report an error with the given message for the given source element.
  */
 protected void error(String message, Element source, Throwable cause) {
  this.readerContext.error(message, source, this.parseState.snapshot(), cause);
 }

弹射错误。

/**
  * Initialize the default lazy-init, autowire, dependency check settings,
  * init-method, destroy-method and merge settings. Support nested 'beans'
  * element use cases by falling back to the given parent in case the
  * defaults are not explicitly set locally.
  * @see #populateDefaults(DocumentDefaultsDefinition, DocumentDefaultsDefinition, org.w3c.dom.Element)
  * @see #getDefaults()
  */
 public void initDefaults(Element root, BeanDefinitionParserDelegate parent) {
  populateDefaults(this.defaults, (parent != null ? parent.defaults : null), root);
  this.readerContext.fireDefaultsRegistered(this.defaults);
 }
 /**
  * Initialize the default settings assuming a {@code null} parent delegate.
  * @deprecated in Spring 3.1 in favor of
  * {@link #initDefaults(Element, BeanDefinitionParserDelegate)}
  */
 public void initDefaults(Element root) {
  initDefaults(root, null);
 }

初始化所有。

 /**
  * Populate the given DocumentDefaultsDefinition instance with the default lazy-init,
  * autowire, dependency check settings, init-method, destroy-method and merge settings.
  * Support nested 'beans' element use cases by falling back to
  * <literal>parentDefaults</literal> in case the defaults are not explicitly set
  * locally.
  * @param defaults the defaults to populate
  * @param defaults the parent BeanDefinitionParserDelegate (if any) defaults to fall back to
  * @param root the root element of the current bean definition document (or nested beans element)
  */
 protected void populateDefaults(DocumentDefaultsDefinition defaults, DocumentDefaultsDefinition parentDefaults, Element root) {
  String lazyInit = root.getAttribute(DEFAULT_LAZY_INIT_ATTRIBUTE);
  if (DEFAULT_VALUE.equals(lazyInit)) {
   lazyInit = parentDefaults != null ? parentDefaults.getLazyInit() : FALSE_VALUE;
  }
  defaults.setLazyInit(lazyInit);
  String merge = root.getAttribute(DEFAULT_MERGE_ATTRIBUTE);
  if (DEFAULT_VALUE.equals(merge)) {
   merge = parentDefaults != null ? parentDefaults.getMerge() : FALSE_VALUE;
  }
  defaults.setMerge(merge);
  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.
  defaults.setDependencyCheck(root.getAttribute(DEFAULT_DEPENDENCY_CHECK_ATTRIBUTE));
  if (root.hasAttribute(DEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE)) {
   defaults.setAutowireCandidates(root.getAttribute(DEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE));
  }
  else if (parentDefaults != null) {
   defaults.setAutowireCandidates(parentDefaults.getAutowireCandidates());
  }
  if (root.hasAttribute(DEFAULT_INIT_METHOD_ATTRIBUTE)) {
   defaults.setInitMethod(root.getAttribute(DEFAULT_INIT_METHOD_ATTRIBUTE));
  }
  else if (parentDefaults != null) {
   defaults.setInitMethod(parentDefaults.getInitMethod());
  }
  if (root.hasAttribute(DEFAULT_DESTROY_METHOD_ATTRIBUTE)) {
   defaults.setDestroyMethod(root.getAttribute(DEFAULT_DESTROY_METHOD_ATTRIBUTE));
  }
  else if (parentDefaults != null) {
   defaults.setDestroyMethod(parentDefaults.getDestroyMethod());
  }
  defaults.setSource(this.readerContext.extractSource(root));
 }

主要是用来配置属性,原则是没有配置检测属性就从父类的DocumentDefaultsDefinition取得。

/**
  * Return the defaults definition object, or <code>null</code> if the
  * defaults have been initialized yet.
  */
 public DocumentDefaultsDefinition getDefaults() {
  return this.defaults;
 }

取得默认的DocumentDefaultsDefinition。

/**
  * Return the default settings for bean definitions as indicated within
  * the attributes of the top-level <code>&lt;beans/&gt;</code> element.
  */
 public BeanDefinitionDefaults getBeanDefinitionDefaults() {
  BeanDefinitionDefaults bdd = new BeanDefinitionDefaults();
  bdd.setLazyInit("TRUE".equalsIgnoreCase(this.defaults.getLazyInit()));
  bdd.setDependencyCheck(this.getDependencyCheck(DEFAULT_VALUE));
  bdd.setAutowireMode(this.getAutowireMode(DEFAULT_VALUE));
  bdd.setInitMethodName(this.defaults.getInitMethod());
  bdd.setDestroyMethodName(this.defaults.getDestroyMethod());
  return bdd;
 }

默认的Beandefinition。

/**
  * Parses the supplied <code>&lt;bean&gt;</code> element. May return <code>null</code>
  * if there were errors during parse. Errors are reported to the
  * {@link org.springframework.beans.factory.parsing.ProblemReporter}.
  */
 public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
  return parseBeanDefinitionElement(ele, null);
 }

转换BeanDefinition,调用下面的方法。

/**
  * Parses the supplied <code>&lt;bean&gt;</code> element. May return <code>null</code>
  * if there were errors during parse. Errors are reported to the
  * {@link org.springframework.beans.factory.parsing.ProblemReporter}.
  */
 public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
  String id = ele.getAttribute(ID_ATTRIBUTE);
  String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
  List<String> aliases = new ArrayList<String>();
  if (StringUtils.hasLength(nameAttr)) {
   String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
   aliases.addAll(Arrays.asList(nameArr));
  }
  String beanName = id;
  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");
   }
  }
  if (containingBean == null) {
   checkNameUniqueness(beanName, aliases, ele);
  }
  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);
      // 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);
   return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
  }
  return null;
 }

关键的方法。parseBeanDefinitionElement。下一篇会继续。

你可能感兴趣的:(对dom树的解析封装成应有的数据结构--BeanDefinitionParserDelegate)