Spring中解析非默认命名空间
解析非Spring默认的命名空间
Spring 对于非默认的命名空间,会使用它对应的 NamespaceHandler 进行处理,在BeanDefinitionParserDelegate 的 parseCustomElement 方法中处理自定义元素
这些 NamespaceHandler 从NamespaceHandlerResolver 获取,默认的 NamespaceHandlerResolver 会从类路径下的 META-INF/spring.handlers 中获取
获取到 NamespaceHandler 后,使用这个 NamespaceHandler 的 parse 方法处理当前元素,最后返回处理后生成的 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
可以通过设置 XmlBeanDefinitionReader 的 setNamespaceHandlerResolver 方法,设置自定义的 NamespaceHandlerResolver
在 XmlBeanDefinitonReader 调用 registerBeanDefinitions 方法获取 bean 定义时,会创建一个 XmlReaderContext 对象,这个对象用于保存 XmlBeanDefinitionReader 和 NamespaceHandlerResolver,所以在创建这个对象时,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 方法会先获取当前NamespaceHandler和namespaceUri的映射关系,这个映射关系从 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");
}

浙公网安备 33010602011771号