Loading

Spring中解析非默认命名空间

解析非Spring默认的命名空间

Spring 对于非默认的命名空间,会使用它对应的 NamespaceHandler 进行处理,在BeanDefinitionParserDelegateparseCustomElement 方法中处理自定义元素

这些 NamespaceHandlerNamespaceHandlerResolver 获取,默认的 NamespaceHandlerResolver 会从类路径下的 META-INF/spring.handlers 中获取

获取到 NamespaceHandler 后,使用这个 NamespaceHandlerparse 方法处理当前元素,最后返回处理后生成的 bean 定义

public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
    String namespaceUri = this.getNamespaceURI(ele);
    if (namespaceUri == null) {
        return null;
    } else {
        NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
        if (handler == null) {
            this.error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
            return null;
        } else {
            return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
        }
    }
}

NamespaceHandler

public interface NamespaceHandler {
    
    // 在解析XML元素之前调用
    // 通常用于创建BeanDefinitionParser并保存起来
    void init();

    // 找到合适的BeanDefinitonParser然后调用其parse方法解析XML元素,注册 bean 定义
    BeanDefinition parse(Element var1, ParserContext var2);
	
    // 解析这个XML元素,生成 bean 定义,然后封装到 BeanDefinitionHolder 中返回
    BeanDefinitionHolder decorate(Node var1, BeanDefinitionHolder var2, ParserContext var3);
}

MvcNamespaceHandler

用于解析 <mvc:..>元素的 NamespaceHandler

public class MvcNamespaceHandler extends NamespaceHandlerSupport {
    public MvcNamespaceHandler() {
    }

    public void init() {
        this.registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
        this.registerBeanDefinitionParser("default-servlet-handler", new DefaultServletHandlerBeanDefinitionParser());
        this.registerBeanDefinitionParser("interceptors", new InterceptorsBeanDefinitionParser());
        this.registerBeanDefinitionParser("resources", new ResourcesBeanDefinitionParser());
        this.registerBeanDefinitionParser("view-controller", new ViewControllerBeanDefinitionParser());
        this.registerBeanDefinitionParser("redirect-view-controller", new ViewControllerBeanDefinitionParser());
        this.registerBeanDefinitionParser("status-controller", new ViewControllerBeanDefinitionParser());
        this.registerBeanDefinitionParser("view-resolvers", new ViewResolversBeanDefinitionParser());
        this.registerBeanDefinitionParser("tiles-configurer", new TilesConfigurerBeanDefinitionParser());
        this.registerBeanDefinitionParser("freemarker-configurer", new FreeMarkerConfigurerBeanDefinitionParser());
        this.registerBeanDefinitionParser("groovy-configurer", new GroovyMarkupConfigurerBeanDefinitionParser());
        this.registerBeanDefinitionParser("script-template-configurer", new ScriptTemplateConfigurerBeanDefinitionParser());
        this.registerBeanDefinitionParser("cors", new CorsBeanDefinitionParser());
    }
}

init 方法将创建 BeanDefinitionParser 并保存到了 parsers

public abstract class NamespaceHandlerSupport implements NamespaceHandler {
    private final Map<String, BeanDefinitionParser> parsers = new HashMap();
    private final Map<String, BeanDefinitionDecorator> decorators = new HashMap();
    private final Map<String, BeanDefinitionDecorator> attributeDecorators = new HashMap();

    public NamespaceHandlerSupport() {
    }

    @Nullable
    public BeanDefinition parse(Element element, ParserContext parserContext) {
        // 找到元素对应的 BeanDefinitionParser,解析后返回
        BeanDefinitionParser parser = this.findParserForElement(element, parserContext);
        return parser != null ? parser.parse(element, parserContext) : null;
    }

    @Nullable
    private BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext) {
        //...
    }

    @Nullable
    public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) {
        BeanDefinitionDecorator decorator = this.findDecoratorForNode(node, parserContext);
        return decorator != null ? decorator.decorate(node, definition, parserContext) : null;
    }

    @Nullable
    private BeanDefinitionDecorator findDecoratorForNode(Node node, ParserContext parserContext) {
       //...
    }

    protected final void registerBeanDefinitionParser(String elementName, BeanDefinitionParser parser) {
        this.parsers.put(elementName, parser);
    }

    protected final void registerBeanDefinitionDecorator(String elementName, BeanDefinitionDecorator dec) {
        this.decorators.put(elementName, dec);
    }

    protected final void registerBeanDefinitionDecoratorForAttribute(String attrName, BeanDefinitionDecorator dec) {
        this.attributeDecorators.put(attrName, dec);
    }
}

BeanDenitionParser

BeanDenitionParser 主要用于解析自定义的元素

public interface BeanDefinitionParser {
    // 找到合适的BeanDefinitonParser然后解析XML元素,注册 bean 定义
    // 如果这个元素是嵌套形式的,如嵌套在 <property/> 中,应返回这个主BeanDefinition
    // 如果不是嵌套形式的,返回null
    BeanDefinition parse(Element var1, ParserContext var2);
}

AnnotationDrivenBeanDefinitionParser

@Nullable
public BeanDefinition parse(Element element, ParserContext context) {
    Object source = context.extractSource(element);
    XmlReaderContext readerContext = context.getReaderContext();
    CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), source);
    context.pushContainingComponent(compDefinition);
    RuntimeBeanReference contentNegotiationManager = this.getContentNegotiationManager(element, source, context);
    
    // 创建RequestMappingHandlerMapping的 bean 定义
    RootBeanDefinition handlerMappingDef = new RootBeanDefinition(RequestMappingHandlerMapping.class);
  	//...设置属性
    // 注册 RequestMappingHandlerMapping 的 bean 定义
    readerContext.getRegistry().registerBeanDefinition(HANDLER_MAPPING_BEAN_NAME, handlerMappingDef);
    
    //...
    // 创建RequestMappingHandlerAdapter的 bean 定义
    RootBeanDefinition handlerAdapterDef = new RootBeanDefinition(RequestMappingHandlerAdapter.class);
    //...设置属性
    // 注册RequestMappingHandlerAdapter的 bean 定义
    readerContext.getRegistry().registerBeanDefinition(HANDLER_ADAPTER_BEAN_NAME, handlerAdapterDef);
    
    // 创建CompositeUriComponentsContributorFactoryBean的 bean 定义
    RootBeanDefinition uriContributorDef = new RootBeanDefinition(CompositeUriComponentsContributorFactoryBean.class);
	//... 设置属性
    // 注册CompositeUriComponentsContributorFactoryBean的 bean定义
    readerContext.getRegistry().registerBeanDefinition(uriContributorName, uriContributorDef);

  	//创建MappedInterceptor的bean定义
     RootBeanDefinition mappedInterceptorDef = new RootBeanDefinition(MappedInterceptor.class);
    //...设置属性
    // 注册 MappedInterceptor的 bean 定义
    String mappedInterceptorName = readerContext.registerWithGeneratedName(mappedInterceptorDef);
    
    // 创建ExceptionHandlerExceptionResolver的 bean 定义
    RootBeanDefinition methodExceptionResolver = new RootBeanDefinition(ExceptionHandlerExceptionResolver.class);
 	//...设置属性
	// 注册ExceptionHandlerExceptionResolver的 bean 定义
    String methodExResolverName = readerContext.registerWithGeneratedName(methodExceptionResolver);
    
    // 创建ResponseStatusExceptionResolver的 bean 定义
        RootBeanDefinition statusExceptionResolver = new RootBeanDefinition(ResponseStatusExceptionResolver.class);
    //... 设置属性
    String statusExResolverName = readerContext.registerWithGeneratedName(statusExceptionResolver);
    
    // 创建ResponseStatusExceptionResolver的 bean 定义
	RootBeanDefinition defaultExceptionResolver = new RootBeanDefinition(DefaultHandlerExceptionResolver.class);
    // ...设置属性
    // 注册ResponseStatusExceptionResolver的 bean 定义
    String defaultExResolverName = readerContext.registerWithGeneratedName(defaultExceptionResolver);
    // 将这些 bean 定义同一添加到ComponentDefinition中,并发布事件
    // 事件可以由ReaderContext中的ReaderEventListener接收,默认是空的
    // 通过调用XmlBeanDefinitionReader的setEventListener设置自定义的事件监听器
    context.registerComponent(new BeanComponentDefinition(handlerMappingDef, HANDLER_MAPPING_BEAN_NAME));
    context.registerComponent(new BeanComponentDefinition(handlerAdapterDef, HANDLER_ADAPTER_BEAN_NAME));
    context.registerComponent(new BeanComponentDefinition(uriContributorDef, uriContributorName));
    context.registerComponent(new BeanComponentDefinition(mappedInterceptorDef, mappedInterceptorName));
    context.registerComponent(new BeanComponentDefinition(methodExceptionResolver, methodExResolverName));
    context.registerComponent(new BeanComponentDefinition(statusExceptionResolver, statusExResolverName));
    context.registerComponent(new BeanComponentDefinition(defaultExceptionResolver, defaultExResolverName));
    MvcNamespaceUtils.registerDefaultComponents(context, source);
    context.popAndRegisterContainingComponent();
    return null;
}

NamespaceHandlerResolver

public interface NamespaceHandlerResolver {
	// 根据namespaceUri获取NamespaceHandler
    NamespaceHandler resolve(String var1);
}

这个接口用于根据 namespaceUri 获取对应的 NamespaceHandler

可以通过设置 XmlBeanDefinitionReadersetNamespaceHandlerResolver 方法,设置自定义的 NamespaceHandlerResolver

XmlBeanDefinitonReader 调用 registerBeanDefinitions 方法获取 bean 定义时,会创建一个 XmlReaderContext 对象,这个对象用于保存 XmlBeanDefinitionReaderNamespaceHandlerResolver,所以在创建这个对象时,XmlBeanDefinitonReader 会将自身和当前保存的 NamespaceHandlerResolver 作为构造方法参数传入,如果XmlBeanDefinitonReader没有设置XmlBeanDefinitonReader,那么就会创建一个DefaultNamespaceHandlerResolver

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
    BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader();
    int countBefore = this.getRegistry().getBeanDefinitionCount();
    // 传入当前XmlBeanDefinitonReader对象和XmlReaderContext
    documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
    return this.getRegistry().getBeanDefinitionCount() - countBefore;
}
public XmlReaderContext createReaderContext(Resource resource) {
    // 传入当前对象、命名空间处理器解析器、配置文件资源、问题报告器、读取bean定义的事件监听器等等
    return new XmlReaderContext(resource, this.problemReporter, this.eventListener, this.sourceExtractor, this, this.getNamespaceHandlerResolver());
}
public NamespaceHandlerResolver getNamespaceHandlerResolver() {
    if (this.namespaceHandlerResolver == null) {
        this.namespaceHandlerResolver = this.createDefaultNamespaceHandlerResolver();
    }

    return this.namespaceHandlerResolver;
}

DefaultNamespaceHandlerResolver

Spring 中默认的 DefaultNamespaceHandlerResolver 会从类路径下的 META-INF/spring.handlers 文件中读取NamespaceHandler的类名,然后进行实例化

DefaultNamespaceHandlerResolver 调用 resolve 方法会先获取当前NamespaceHandlernamespaceUri的映射关系,这个映射关系从 handlerMappingsLocation 这个位置的 properties 文件中获取,而handlerMappingsLocation 属性在调用构造器时被赋值为 META-INF/spring.handlers

获取到类名后,根据类名实例化,然后将映射关系加入handlerMappings

public NamespaceHandler resolve(String namespaceUri) {
    // 获取当前NamespaceHandler和namespaceUri的映射关系
    Map<String, Object> handlerMappings = this.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");
            } else {
                NamespaceHandler namespaceHandler = (NamespaceHandler)BeanUtils.instantiateClass(handlerClass);
                // 调用NamespaceHandler的初始化方法
                namespaceHandler.init();
                handlerMappings.put(namespaceUri, namespaceHandler);
                return namespaceHandler;
            }
        } catch (ClassNotFoundException var7) {
            throw new FatalBeanException("Could not find NamespaceHandler class [" + className + "] for namespace [" + namespaceUri + "]", var7);
        } catch (LinkageError var8) {
            throw new FatalBeanException("Unresolvable class definition for NamespaceHandler class [" + className + "] for namespace [" + namespaceUri + "]", var8);
        }
    }
}
private Map<String, Object> getHandlerMappings() {
    Map<String, Object> handlerMappings = this.handlerMappings;
    // 如果当前map是null
    if (handlerMappings == null) {
        synchronized(this) {
            handlerMappings = this.handlerMappings;
            // 从指定properties获取NamespaceHandler类名
            if (handlerMappings == null) {
                if (this.logger.isTraceEnabled()) {
                    this.logger.trace("Loading NamespaceHandler mappings from [" + this.handlerMappingsLocation + "]");
                }

                try {
                    Properties mappings = PropertiesLoaderUtils.loadAllProperties(this.handlerMappingsLocation, this.classLoader);
                    if (this.logger.isTraceEnabled()) {
                        this.logger.trace("Loaded NamespaceHandler mappings: " + mappings);
                    }

                    handlerMappings = new ConcurrentHashMap(mappings.size());
                    CollectionUtils.mergePropertiesIntoMap(mappings, (Map)handlerMappings);
                    this.handlerMappings = (Map)handlerMappings;
                } catch (IOException var5) {
                    throw new IllegalStateException("Unable to load NamespaceHandler mappings from location [" + this.handlerMappingsLocation + "]", var5);
                }
            }
        }
    }

    return (Map)handlerMappings;
}
public DefaultNamespaceHandlerResolver() {
    this((ClassLoader)null, "META-INF/spring.handlers");
}
posted @ 2022-08-14 18:24  7shuo  阅读(65)  评论(0)    收藏  举报