让我们先看BeanDefinitionParserDelegate类的parseCustomElement方法:
public BeanDefinition parseCustomElement(Element ele) { return parseCustomElement(ele, null); } //containingBd为父类bean,对顶层元素的解析应设置为null public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) { String namespaceUri = getNamespaceURI(ele); //根据命名空间找到对应的NamespaceHandler进行解析 NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri); if (handler == null) { error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele); return null; } //调用自定义的NamespaceHandler进行解析 return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd)); }
/** * 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 */ public NamespaceHandler resolve(String namespaceUri) { //获取所有已经配置的handler映射 Map<String, Object> handlerMappings = getHandlerMappings(); //根据命名空间找打对应信息 Object handlerOrClassName = handlerMappings.get(namespaceUri); if (handlerOrClassName == null) { return null; } else if (handlerOrClassName instanceof NamespaceHandler) { //已做过解析的情况,直接从缓存读取 return (NamespaceHandler) handlerOrClassName; } else { //没有做过解析,则返回的是类路径 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的初始化方法 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); } } }
/** * * @author Administrator */ public class MyNamespaceHandler extends NamespaceHandlerSupport { /* (non-Javadoc) * @see org.springframework.beans.factory.xml.NamespaceHandler#init() */ @Override public void init() { registerBeanDefinitionParser("user", new UserBeanDefinitionParser()); } }
/** * Load the specified NamespaceHandler mappings lazily. */ private Map<String, Object> getHandlerMappings() { //如果没有被缓存,则开始进入缓存 if (this.handlerMappings == null) { synchronized (this) { if (this.handlerMappings == null) { try { //this.handlerMappings在构造函数已被初始化为META-INF/Spring.handlers 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()); //将properties文件合并到Map格式的handlerMappings中 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; }
让我们回到BeanDefinitionParserDelegate的handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));中
进入NamespaceHandlerSupport中的parse方法
/** * Parses the supplied {@link Element} by delegating to the {@link BeanDefinitionParser} that is * registered for that {@link Element}. */ public BeanDefinition parse(Element element, ParserContext parserContext) { //寻找解析器,并进行解析操作 return findParserForElement(element, parserContext).parse(element, parserContext); } /** * Locates the {@link BeanDefinitionParser} from the register implementations using * the local name of the supplied {@link Element}. */ private BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext) { //获取元素名称,也就是<myname:user 中的user,此时localname为user String localName = parserContext.getDelegate().getLocalName(element); //根据user找到对应的解析器也就是在 //registerBeanDefinitionParser("user", new UserBeanDefinitionParser());注册的解析器 BeanDefinitionParser parser = this.parsers.get(localName); if (parser == null) { parserContext.getReaderContext().fatal( "Cannot locate BeanDefinitionParser for element [" + localName + "]", element); } return parser; }
public final BeanDefinition parse(Element element, ParserContext parserContext) { AbstractBeanDefinition definition = parseInternal(element, parserContext); if (definition != null && !parserContext.isNested()) { try { String id = resolveId(element, definition, parserContext); if (!StringUtils.hasText(id)) { parserContext.getReaderContext().error( "Id is required for element '" + parserContext.getDelegate().getLocalName(element) + "' when used as a top-level tag", element); } String[] aliases = new String[0]; String name = element.getAttribute(NAME_ATTRIBUTE); if (StringUtils.hasLength(name)) { aliases = StringUtils.trimArrayElements(StringUtils.commaDelimitedListToStringArray(name)); } //将AbstractBeanDefinition转换成BeanDefinitionHolder BeanDefinitionHolder holder = new BeanDefinitionHolder(definition, id, aliases); registerBeanDefinition(holder, parserContext.getRegistry()); if (shouldFireEvents()) { //需要通知监听器进行处理 BeanComponentDefinition componentDefinition = new BeanComponentDefinition(holder); postProcessComponentDefinition(componentDefinition); parserContext.registerComponent(componentDefinition); } } catch (BeanDefinitionStoreException ex) { parserContext.getReaderContext().error(ex.getMessage(), element); return null; } } return definition; }
接下来,让我们看看parseInternal方法,先跟踪到AbstractSingleBeanDefinitionParser
/** * Creates a {@link BeanDefinitionBuilder} instance for the * {@link #getBeanClass bean Class} and passes it to the * {@link #doParse} strategy method. * @param element the element that is to be parsed into a single BeanDefinition * @param parserContext the object encapsulating the current state of the parsing process * @return the BeanDefinition resulting from the parsing of the supplied {@link Element} * @throws IllegalStateException if the bean {@link Class} returned from * {@link #getBeanClass(org.w3c.dom.Element)} is {@code null} * @see #doParse */ @Override protected final AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(); String parentName = getParentName(element); if (parentName != null) { builder.getRawBeanDefinition().setParentName(parentName); } //获取自定义标签中的class,此时会调用自定义解析器,如UserBeanDefinitionParser中的getBeanClass方法 Class<?> beanClass = getBeanClass(element); if (beanClass != null) { builder.getRawBeanDefinition().setBeanClass(beanClass); } else { //若子类没有重写getBeanClass方法则尝试检查子类是否重写getBeanClassName方法 String beanClassName = getBeanClassName(element); if (beanClassName != null) { builder.getRawBeanDefinition().setBeanClassName(beanClassName); } } builder.getRawBeanDefinition().setSource(parserContext.extractSource(element)); if (parserContext.isNested()) { // Inner bean definition must receive same scope as containing bean. builder.setScope(parserContext.getContainingBeanDefinition().getScope()); } if (parserContext.isDefaultLazyInit()) { // Default-lazy-init applies to custom bean definitions as well. builder.setLazyInit(true); } doParse(element, parserContext, builder); return builder.getBeanDefinition(); }