Spring是怎么擴(kuò)展解析xml接口的

自定義Spring配置
BeanDefinitionParserDelegate
在DefaultBeanDefinitionDocumentReader處理Document元素時(shí),將Document文檔內(nèi)元素具體解析工作委托給BeanDefinitionParserDelegate類來(lái)處理,默認(rèn)BeanDefinitionParserDelegate會(huì)處理”
public class BeanDefinitionParserDelegate {
public static final String BEANS_NAMESPACE_URI = "http://www.springframework.org/schema/beans";
public static final String MULTI_VALUE_ATTRIBUTE_DELIMITERS = ",; ";
private final XmlReaderContext readerContext;
private final DocumentDefaultsDefinition defaults = new DocumentDefaultsDefinition();
/**
*初始化 default lazy-init, autowire, dependency check settings,
* init-method, destroy-method and merge settings等屬性值
* 并且填充到屬性 DocumentDefaultsDefinition defaults;
* 如果 當(dāng)前Xml文件沒(méi)有配置默認(rèn)屬性,則查父類delegate有沒(méi)有設(shè)置屬性;如果沒(méi)有則 使用默認(rèn)配置
*/
protected void populateDefaults(DocumentDefaultsDefinition defaults, DocumentDefaultsDefinition parentDefaults, Element root) {
String lazyInit = root.getAttribute(DEFAULT_LAZY_INIT_ATTRIBUTE);
if (DEFAULT_VALUE.equals(lazyInit)) {
// Potentially inherited from outer <beans> sections, otherwise falling back to false.
lazyInit = (parentDefaults != null ? parentDefaults.getLazyInit() : FALSE_VALUE);
}
defaults.setLazyInit(lazyInit);
String merge = root.getAttribute(DEFAULT_MERGE_ATTRIBUTE);
if (DEFAULT_VALUE.equals(merge)) {
// Potentially inherited from outer <beans> sections, otherwise falling back to false.
merge = (parentDefaults != null ? parentDefaults.getMerge() : FALSE_VALUE);
}
defaults.setMerge(merge);
String autowire = root.getAttribute(DEFAULT_AUTOWIRE_ATTRIBUTE);
if (DEFAULT_VALUE.equals(autowire)) {
// Potentially inherited from outer <beans> sections, otherwise falling back to 'no'.
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));
}
//解析自定義元素
public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
//獲取當(dāng)前Element的命名空間
String namespaceUri = getNamespaceURI(ele);
//獲取namespaceHandlerResolver然后根據(jù)命名空間得到具體的 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處理類去解析Element;返回 BeanDefinition 對(duì)象
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
//返回defaults屬性值
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;
}DefaultNamespaceHandlerResolver
DefaultNamespaceHandlerResolver implements NamespaceHandlerResolver; 默認(rèn)的 命名空間解析對(duì)象選擇器; 主要作用就是 根據(jù)不同的命名空間來(lái)選擇對(duì)應(yīng)的解析器;
/**
* 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
*/
@Override
public NamespaceHandler resolve(String namespaceUri) {
Map<String, Object> handlerMappings = getHandlerMappings();
Object handlerOrClassName = handlerMappings.get(namespaceUri);
if (handlerOrClassName == null) {
return null;
}
//如果已經(jīng)把全類名路徑轉(zhuǎn)換成具體的實(shí)例了 就直接返回
else if (handlerOrClassName instanceof NamespaceHandler) {
return (NamespaceHandler) handlerOrClassName;
}
else {
String className = (String) handlerOrClassName;
try {
//根據(jù)全類名路徑 來(lái)加載這個(gè)類
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");
}
//加載完類之后,通過(guò)反射生成具體實(shí)例對(duì)象;例如:ContextNamespaceHandler
NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
//調(diào)用具體對(duì)象的init()方法,注冊(cè)對(duì)應(yīng)的解析類,例如annotation-config 對(duì)應(yīng)的解析類是 AnnotationConfigBeanDefinitionParser
namespaceHandler.init();
//將實(shí)例對(duì)象覆蓋 全類名路徑
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);
}
}
}
/**
* 第一次加載的時(shí)候 Map里面的對(duì)象 是String類型,全類名路徑
*/
private Map<String, Object> getHandlerMappings() {
if (this.handlerMappings == null) {
synchronized (this) {
if (this.handlerMappings == null) {
//加載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());
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;
}NamespaceHandlerSupport implements NamespaceHandler
實(shí)現(xiàn)了NamespaceHandler中的parse()和decorate方法,并且提供一些屬性來(lái)維護(hù) 具體的解析元素的對(duì)象BeanDefinitionParser; 例如:www.springframework.org/schema/cont… 命名空間對(duì)應(yīng)的操作類是 ContextNamespaceHandler; 這個(gè)操作類會(huì)調(diào)用init()方法
@Override
public void init() {
registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
}根據(jù)不同的屬性,注冊(cè)不同的解析類 BeanDefinitionParser

我們以ContextNamespaceHandler看下, 實(shí)現(xiàn)類只要實(shí)現(xiàn)init方法就行了; 對(duì)應(yīng)的解析類 通過(guò)registerBeanDefinitionParser方法,存放到NamespaceHandlerSupport中的Map parsers 中

public abstract class NamespaceHandlerSupport implements NamespaceHandler {
//將元素頭 與對(duì)應(yīng)的解析器對(duì)應(yīng)起來(lái)
protected final void registerBeanDefinitionParser(String elementName, BeanDefinitionParser parser) {
this.parsers.put(elementName, parser);
}
/**
*具體的NamespaceHandler處理類去解析Element;返回 BeanDefinition 對(duì)象
* BeanDefinitionParserDelegate.parseCustomElement 中 在獲取到了對(duì)應(yīng)的handler后,會(huì)執(zhí)行handler.parse(ele, new ParserContext(this.readerContext, this, containingBd))方法;
* 例如:獲取到的操作類是 ContextNamespaceHandler,調(diào)用parse的方法其實(shí)調(diào)用了NamespaceHandlerSupportde parse方法;也就是下面的
* 例如annotation-config得到的是AnnotationConfigBeanDefinitionParser實(shí)例, 再調(diào)用AnnotationConfigBeanDefinitionParser的parse方法;這樣就實(shí)現(xiàn)了根據(jù)不同元素來(lái)解析成 Spring中的 定義Bean BeanDefinition了;
*/
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
return findParserForElement(element, parserContext).parse(element, parserContext);
}
/**
* 根據(jù)元素節(jié)點(diǎn)的名稱 獲取對(duì)應(yīng)的解析類實(shí)例;例如annotation-config得到的是AnnotationConfigBeanDefinitionParser實(shí)例,
*/
private BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext) {
String localName = parserContext.getDelegate().getLocalName(element);
BeanDefinitionParser parser = this.parsers.get(localName);
if (parser == null) {
parserContext.getReaderContext().fatal(
"Cannot locate BeanDefinitionParser for element [" + localName + "]", element);
}
return parser;
}
}public class ContextNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
}
}BeanDefinitionParser
Element元素的解析類;只有一個(gè)方法BeanDefinition parse(Element element, ParserContext parserContext); 實(shí)現(xiàn)類去實(shí)現(xiàn)這個(gè)方法就行了;
我們看到parse方法中傳入了ParserContext 參數(shù);我們了解一下這個(gè);
ParserContext
解析類上下文;這類hold住了 XmlReaderContext和 BeanDefinitionParserDelegate;可以最大限度的讓用戶自已去解析
public ParserContext(XmlReaderContext readerContext, BeanDefinitionParserDelegate delegate,
BeanDefinition containingBeanDefinition) {
this.readerContext = readerContext;
this.delegate = delegate;
this.containingBeanDefinition = containingBeanDefinition;
}到此這篇關(guān)于Spring是怎么擴(kuò)展解析xml接口的的文章就介紹到這了,更多相關(guān)Spring解析xml接口內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺談Mybatis+mysql 存儲(chǔ)Date類型的坑
這篇文章主要介紹了淺談Mybatis+mysql 存儲(chǔ)Date類型的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11
spring學(xué)習(xí)之util:properties的使用
這篇文章主要介紹了spring學(xué)習(xí)之util:properties的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01
logback.xml動(dòng)態(tài)配置程序路徑的操作
這篇文章主要介紹了logback.xml動(dòng)態(tài)配置程序路徑的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-02-02
spring mvc高級(jí)技術(shù)實(shí)例詳解
前面學(xué)習(xí)了簡(jiǎn)單的Spring Web知識(shí),接著學(xué)習(xí)更高階的Web技術(shù)。下面這篇文章主要給大家介紹了spring mvc高級(jí)技術(shù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起看看吧2018-09-09
詳解如何使用java實(shí)現(xiàn)Open Addressing
這篇文章主要介紹了詳解如何使用java實(shí)現(xiàn)Open Addressing,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12
java面試題——詳解HashMap和Hashtable 的區(qū)別
本篇文章主要介紹了java中HashMap和Hashtable的區(qū)別,具有一定的參考價(jià)值,有需要的可以了解一下。2016-11-11

