Spring 启动记录(7)

Spring 的NamSpaceHandlerResolver

1、此时的spring 已经获取到了ResourceLoader获取的File,创建了Document对象,

接下来进一步创建了DefaultBeanDefinitionDocumentReader对象的registerBeanDefinitions来解析注册xml属性

 

此时该方法需要

public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
   this.readerContext = readerContext;
   logger.debug("Loading bean definitions");
   Element root = doc.getDocumentElement();
   doRegisterBeanDefinitions(root);
}

 

public XmlReaderContext createReaderContext(Resource resource) {
   return new XmlReaderContext(resource, this.problemReporter, this.eventListener,
         this.sourceExtractor, this, getNamespaceHandlerResolver());
}

202932_BHDm_867830.png

 

/*
 * Copyright 2002-2007 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans.factory.parsing;

import org.springframework.core.io.Resource;

/**
 * Context that gets passed along a bean definition reading process,
 * encapsulating all relevant configuration as well as state.
 *
 * @author Rob Harrop
 * @author Juergen Hoeller
 * @since 2.0
 */
public class ReaderContext {

   private final Resource resource;

   private final ProblemReporter problemReporter;

   private final ReaderEventListener eventListener;

   private final SourceExtractor sourceExtractor;

   public ReaderContext(Resource resource, ProblemReporter problemReporter,
         ReaderEventListener eventListener, SourceExtractor sourceExtractor) {

      this.resource = resource;
      this.problemReporter = problemReporter;
      this.eventListener = eventListener;
      this.sourceExtractor = sourceExtractor;
   }

   public final Resource getResource() {
      return this.resource;
   }
   //---------------------------------------
   //----------处理解析异常,如xml某行非法字符或者元素名称不对---------
   public void fatal(String message, Object source) {
      fatal(message, source, null, null);
   }

   public void fatal(String message, Object source, Throwable ex) {
      fatal(message, source, null, ex);
   }

   public void fatal(String message, Object source, ParseState parseState) {
      fatal(message, source, parseState, null);
   }

   public void fatal(String message, Object source, ParseState parseState, Throwable cause) {
      Location location = new Location(getResource(), source);
      this.problemReporter.fatal(new Problem(message, location, parseState, cause));
   }

   public void error(String message, Object source) {
      error(message, source, null, null);
   }

   public void error(String message, Object source, Throwable ex) {
      error(message, source, null, ex);
   }

   public void error(String message, Object source, ParseState parseState) {
      error(message, source, parseState, null);
   }

   public void error(String message, Object source, ParseState parseState, Throwable cause) {
      Location location = new Location(getResource(), source);
      this.problemReporter.error(new Problem(message, location, parseState, cause));
   }

   public void warning(String message, Object source) {
      warning(message, source, null, null);
   }

   public void warning(String message, Object source, Throwable ex) {
      warning(message, source, null, ex);
   }

   public void warning(String message, Object source, ParseState parseState) {
      warning(message, source, parseState, null);
   }

   public void warning(String message, Object source, ParseState parseState, Throwable cause) {
      Location location = new Location(getResource(), source);
      this.problemReporter.warning(new Problem(message, location, parseState, cause));
   }

   //-------------------------------
   //-----------向注册的监听发出事件
   public void fireDefaultsRegistered(DefaultsDefinition defaultsDefinition) {
      this.eventListener.defaultsRegistered(defaultsDefinition);
   }

   public void fireComponentRegistered(ComponentDefinition componentDefinition) {
      this.eventListener.componentRegistered(componentDefinition);
   }

   public void fireAliasRegistered(String beanName, String alias, Object source) {
      this.eventListener.aliasRegistered(new AliasDefinition(beanName, alias, source));
   }

   public void fireImportProcessed(String importedResource, Object source) {
      this.eventListener.importProcessed(new ImportDefinition(importedResource, source));
   }

   public void fireImportProcessed(String importedResource, Resource[] actualResources, Object source) {
      this.eventListener.importProcessed(new ImportDefinition(importedResource, actualResources, source));
   }


   public SourceExtractor getSourceExtractor() {
      return this.sourceExtractor;
   }

   public Object extractSource(Object sourceCandidate) {
      return this.sourceExtractor.extractSource(sourceCandidate, this.resource);
   }

}

 

子类XmlReaderContext:

/*
 * Copyright 2002-2014 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans.factory.xml;

import java.io.StringReader;

import org.w3c.dom.Document;
import org.xml.sax.InputSource;

import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.parsing.ProblemReporter;
import org.springframework.beans.factory.parsing.ReaderContext;
import org.springframework.beans.factory.parsing.ReaderEventListener;
import org.springframework.beans.factory.parsing.SourceExtractor;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;

/**
 * Extension of {@link org.springframework.beans.factory.parsing.ReaderContext},
 * specific to use with an {@link XmlBeanDefinitionReader}. Provides access to the
 * {@link NamespaceHandlerResolver} configured in the {@link XmlBeanDefinitionReader}.
 *
 * @author Rob Harrop
 * @author Juergen Hoeller
 * @since 2.0
 */
public class XmlReaderContext extends ReaderContext {

   private final XmlBeanDefinitionReader reader;
   
  //此类是处理Xml的xsd空间解析的处理相应的xml定义元素,xml核心的处理对象
   private final NamespaceHandlerResolver namespaceHandlerResolver;


   public XmlReaderContext(
         Resource resource, ProblemReporter problemReporter,
         ReaderEventListener eventListener, SourceExtractor sourceExtractor,
         XmlBeanDefinitionReader reader, NamespaceHandlerResolver namespaceHandlerResolver) {

      super(resource, problemReporter, eventListener, sourceExtractor);
      this.reader = reader;
      this.namespaceHandlerResolver = namespaceHandlerResolver;
   }


   public final XmlBeanDefinitionReader getReader() {
      return this.reader;
   }

   public final BeanDefinitionRegistry getRegistry() {
      return this.reader.getRegistry();
   }

   public final ResourceLoader getResourceLoader() {
      return this.reader.getResourceLoader();
   }

   public final ClassLoader getBeanClassLoader() {
      return this.reader.getBeanClassLoader();
   }

   public final Environment getEnvironment() {
      return this.reader.getEnvironment();
   }

   public final NamespaceHandlerResolver getNamespaceHandlerResolver() {
      return this.namespaceHandlerResolver;
   }


   public String generateBeanName(BeanDefinition beanDefinition) {
      return this.reader.getBeanNameGenerator().generateBeanName(beanDefinition, getRegistry());
   }

   public String registerWithGeneratedName(BeanDefinition beanDefinition) {
      String generatedName = generateBeanName(beanDefinition);
      getRegistry().registerBeanDefinition(generatedName, beanDefinition);
      return generatedName;
   }

   public Document readDocumentFromString(String documentContent) {
      InputSource is = new InputSource(new StringReader(documentContent));
      try {
         return this.reader.doLoadDocument(is, getResource());
      }
      catch (Exception ex) {
         throw new BeanDefinitionStoreException("Failed to read XML document", ex);
      }
   }

}
/**
 * Lazily create a default NamespaceHandlerResolver, if not set before.
 * @see #createDefaultNamespaceHandlerResolver()
 */
public NamespaceHandlerResolver getNamespaceHandlerResolver() {
   if (this.namespaceHandlerResolver == null) {
      this.namespaceHandlerResolver = createDefaultNamespaceHandlerResolver();
   }
   return this.namespaceHandlerResolver;
}

/**
 * Create the default implementation of {@link NamespaceHandlerResolver} used if none is specified.
 * Default implementation returns an instance of {@link DefaultNamespaceHandlerResolver}.
 */
protected NamespaceHandlerResolver createDefaultNamespaceHandlerResolver() {
   return new DefaultNamespaceHandlerResolver(getResourceLoader().getClassLoader());
}

此时XmlBeanDefinittionReader创建的是DefaultNamespaceHandlerResolver对象

/*
 * Copyright 2002-2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans.factory.xml;



/**
 * Default implementation of the {@link NamespaceHandlerResolver} interface.
 * Resolves namespace URIs to implementation classes based on the mappings
 * contained in mapping file.
 *查找xml的namespace url对应的对象的handler对象
 * <p>By default, this implementation looks for the mapping file at
 * {@code META-INF/spring.handlers}, but this can be changed using the
 * {@link #DefaultNamespaceHandlerResolver(ClassLoader, String)} constructor.
 * 默认的handler对象在META-INF/spring.handlers文件里面定义,次文件如下定义handler
http\://www.springframework.org/schema/c=org.springframework.beans.factory.xml.SimpleConstructorNamespaceHandler
http\://www.springframework.org/schema/p=org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler
http\://www.springframework.org/schema/util=org.springframework.beans.factory.xml.UtilNamespaceHandler
 
 * @author Rob Harrop
 * @author Juergen Hoeller
 * @since 2.0
 * @see NamespaceHandler
 * @see DefaultBeanDefinitionDocumentReader
 */
public class DefaultNamespaceHandlerResolver implements NamespaceHandlerResolver {

   /**
    * The location to look for the mapping files. Can be present in multiple JAR files.
    */
   public static final String DEFAULT_HANDLER_MAPPINGS_LOCATION = "META-INF/spring.handlers";


   /** Logger available to subclasses */
   protected final Log logger = LogFactory.getLog(getClass());

   /** ClassLoader to use for NamespaceHandler classes */
   private final ClassLoader classLoader;

   /** Resource location to search for */
   private final String handlerMappingsLocation;

   /** Stores the mappings from namespace URI to NamespaceHandler class name / instance */
   private volatile Map<String, Object> handlerMappings;


   /**
    * Create a new {@code DefaultNamespaceHandlerResolver} using the
    * default mapping file location.
    * <p>This constructor will result in the thread context ClassLoader being used
    * to load resources.
    * @see #DEFAULT_HANDLER_MAPPINGS_LOCATION
    */
   public DefaultNamespaceHandlerResolver() {
      this(null, DEFAULT_HANDLER_MAPPINGS_LOCATION);
   }

   /**
    * Create a new {@code DefaultNamespaceHandlerResolver} using the
    * default mapping file location.
    * @param classLoader the {@link ClassLoader} instance used to load mapping resources
    * (may be {@code null}, in which case the thread context ClassLoader will be used)
    * @see #DEFAULT_HANDLER_MAPPINGS_LOCATION
    */
   public DefaultNamespaceHandlerResolver(ClassLoader classLoader) {
      this(classLoader, DEFAULT_HANDLER_MAPPINGS_LOCATION);
   }

   /**
    * Create a new {@code DefaultNamespaceHandlerResolver} using the
    * supplied mapping file location.
    * @param classLoader the {@link ClassLoader} instance used to load mapping resources
    * may be {@code null}, in which case the thread context ClassLoader will be used)
    * @param handlerMappingsLocation the mapping file 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;
   }


   /**
    * Locate the {@link NamespaceHandler} for the supplied namespace URI
    * from the configured mappings.
    * @param namespaceUri the relevant namespace URI
    * @return the located {@link NamespaceHandler}, or {@code null} if none found
    * 根据namespaceUri找到对应的handler对象
    */

 
   @Override
   public NamespaceHandler resolve(String namespaceUri) {
      Map<String, Object> handlerMappings = getHandlerMappings();
      Object handlerOrClassName = handlerMappings.get(namespaceUri);
      if (handlerOrClassName == null) {
         return null;
      }
      else if (handlerOrClassName instanceof NamespaceHandler) {
         return (NamespaceHandler) handlerOrClassName;
      }
      else {
      //如果不是NamespaceHandler子类的handler则会抛出异常
         String className = (String) handlerOrClassName;
         try {
            Class<?> handlerClass = ClassUtils.forName(className, this.classLoader);
            if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) {
               throw new FatalBeanException("Class [" + className + "] for namespace [" + namespaceUri +
                     "] does not implement the [" + NamespaceHandler.class.getName() + "] interface");
            }
            NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
            namespaceHandler.init();
            handlerMappings.put(namespaceUri, namespaceHandler);
            return namespaceHandler;
         }
         catch (ClassNotFoundException ex) {
            throw new FatalBeanException("NamespaceHandler class [" + className + "] for namespace [" +
                  namespaceUri + "] not found", ex);
         }
         catch (LinkageError err) {
            throw new FatalBeanException("Invalid NamespaceHandler class [" + className + "] for namespace [" +
                  namespaceUri + "]: problem with handler class file or dependent class", err);
         }
      }
   }

   /**
    * Load the specified NamespaceHandler mappings lazily.
   * 获取相应handler 根据handlerMappingsLocation 读取META-INF/spring.handlers中的内容返回一个map
    */
   private Map<String, Object> getHandlerMappings() {
      if (this.handlerMappings == null) {
         synchronized (this) {
            if (this.handlerMappings == null) {
               try {
                //读取默认的
                  Properties mappings =
                        PropertiesLoaderUtils.loadAllProperties
                                (this.handlerMappingsLocation, this.classLoader);
                  if (logger.isDebugEnabled()) {
                     logger.debug("Loaded NamespaceHandler mappings: " + mappings);
                  }
                  Map<String, Object> handlerMappings = new ConcurrentHashMap<String, Object>(mappings.size());
                  CollectionUtils.mergePropertiesIntoMap(mappings, handlerMappings);
                  this.handlerMappings = handlerMappings;
               }
               catch (IOException ex) {
                  throw new IllegalStateException(
                        "Unable to load NamespaceHandler mappings from location [" + this.handlerMappingsLocation + "]", ex);
               }
            }
         }
      }
      return this.handlerMappings;
   }


   @Override
   public String toString() {
      return "NamespaceHandlerResolver using mappings " + getHandlerMappings();
   }

}

 

至此处得到了XmlReaderContext

210446_QtT4_867830.png

 

到了注册

protected void doRegisterBeanDefinitions(Element root) {
   // 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.
   BeanDefinitionParserDelegate parent = this.delegate;
   this.delegate = createDelegate(getReaderContext(), root, parent);

   if (this.delegate.isDefaultNamespace(root)) {
      String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
      if (StringUtils.hasText(profileSpec)) {
         String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
               profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
         if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
            return;
         }
      }
   }

   preProcessXml(root);
   parseBeanDefinitions(root, this.delegate);
   postProcessXml(root);

   this.delegate = parent;
}

protected BeanDefinitionParserDelegate createDelegate(
      XmlReaderContext readerContext, Element root, BeanDefinitionParserDelegate parentDelegate) {

   BeanDefinitionParserDelegate delegate = new BeanDefinitionParserDelegate(readerContext);
   delegate.initDefaults(root, parentDelegate);
   return delegate;
}

到创建真正的解析Document对象的解析类

BeanDefinitionParserDelegate

 

 

转载于:https://my.oschina.net/u/867830/blog/824587

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值