序文
前のセクションでは、スプリング復号化 - デフォルトタグの分析では、スプリングがデフォルトのタグをどのように解析するかを分析することに焦点を当てます。そのため、この章では、カスタムタグを解析する方法に焦点を当てたラベルの解析について説明し続けています。これ以上苦労せずに、詳細な紹介を見てみましょう。
カスタムタグ
カスタムタグ分析を説明する前に、タグのカスタマイズ方法をご覧ください
XSDファイルを定義します
コンポーネントコンテンツを説明するXSDファイルを定義します
<?xml version = "1.0" encoding = "utf-8"?> <xsd:schema xmlns = "http://www.battcn.com/schema/battcn" xmlns:xsd = "http://www.w3.org/2001/xmlschema" xmlns:beans = "http://www.springframework.org/schema/beans" targetnamespace = "http://www.battcn.com/schema/battcn" elementformdefault = "quatified" abtiontformdefault = " namespace = "http://www.springframework.org/schema/beans"/> <xsd:element name = "application"> <xsd:complentype> <xsd:complexContent> <XSD:拡張ベース= "豆:識別型" </xsd:extension> </xsd:complexContent> </xsd:complextype> </xsd:element> </xsd:schema>
解析ルールを定義します
1. XSDファイルの定義とコンポーネントの定義を解析するために、BeanDefinitionParserインターフェイス(Springが提供するクラスを継承することもできます)を実装するクラスを作成します。
パブリッククラスApplicationBeanDefinitionParserは、AbstractSinglebeanDefinitionParser {@Override Protected Class GetBeanClass(要素要素){//受信オブジェクトのタイプは次のようなものです。 string.classを返します。 } @Override Protected void doparse(element element、beandefinitionbuilder bean){// xsd文字列name = element.getattribute( "name")で定義されている名前属性; bean.addconstructorargvalue(name); }}これは、AbstractSinglebeandefinitionParser(BeanDefinitionParserのサブクラス)を継承するApplicationBeanDefinitionParserです。焦点は、ドパースをオーバーライドし、XMLタグを解析し、その後、コンストラクターに解析された値(レビン)を注入することです。
2。namespacehandlerSupport抽象クラスを継承するクラスを作成します
パブリッククラスbattcnnamespacehandlerは、namespacehandlersupportを拡張します{@override public void init(){RegisterBeanDefinitionParser( "Application"、new ApplicationBeanDefinitionParser()); }} battcnnamespacehandlerの機能は非常にシンプルです。これは、スプリングコンテナ<battcn:application />がそのパーサー(ここではカスタマイズ:ApplicationBeanDefinitionParser)によって解析されるべきであることをスプリングコンテナに伝えることです。
3. spring.handlers and spring.schemasファイルを書きます
ファイルが保存されているディレクトリは、リソース/メタINF/ファイル名にあります
spring.handlers
http/://www.battcn.com/schema/battcn=com.battcn.handler.battcnnamespacehandler
spring.schemas
http/://www.battcn.com/schema/battcn.xsd=battcn.xsd
4.カスタムタグを使用します
次のように定義されているbean.xmlファイルを宣言します
<?xml version = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/xmlschema-instance" xmlns:battcn = "http://www.battcn.com/schema/battcn" xsi:schemalocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schems/schems. http://www.battcn.com/schema/battcn http://www.battcn.com/schema/battcn.xsd "> <battcn:アプリケーションid =" battcn "name =" levin "/> </beans>
テストクラスを作成します。コンソール出力Levin Wordが表示されている場合、カスタムラベルが正常であることを意味します。
public class application {public static void main(string [] args){applicationContext context = new classpathxmlapplicationContext( "bean.xml"); string name =(string)context.getBean( "battcn"); System.out.println(name); }}5。図に示すように
ソースコード分析
カスタムタグ解像度ポータル
Public Class BeanDefinitionParserDelegate {@Nullable Public BeanDefinition ParseCustomElement(Element Ele、@Nullable BeanDefinition CantainsBD){//名前空間アドレスhttp://www.battcn.com/schema/battcn string namespaceuri = getnamespaceuri(ele); if(namespaceuri == null){return null; } // namespacehandlerは、カスタマイズされたbattcnnamespacehandler namespacehandlerハンドラーに登録されているアプリケーションです。 if(handler == null){error( "xml schema namespace [" + namespaceuri + "]"のSpring namespacehandlerを見つけることができない、ele); nullを返します。 } return handler.parse(ele、new parsercontext(this.readercontext、this、containgbd)); }}デフォルトのタグ解像度ルールと同様に、名前空間はgetNamespaceURI(Node node)を介して取得されます。では、 this.readerContext.getNamespaceHandlerResolver()はどこにありますか?コードを追跡すると、プロジェクトが開始されると、すべてのMeta-inf/spring.Handlesファイルのコンテンツがxmlbeandefinitionreaderに解析され、handlermappers(concurrenthashmap)に保存されることがわかります。 resolve(namespaceUri)が呼び出されると、キャッシュされたコンテンツが比較のために抽出されます。
パブリッククラスXMLBEANDEFINITIONREADER {public NameSpaceHandLerRERRESOLVER GETNAMESPACEHANDLERRERESOLVER(){if(this.NamesPaceHandlerResolver == null){this.namesPaceHandlerResolver = createdEfaultNamesSpaceHandLERRERERVER(); } this.namespacehandlerresolverを返します。 }}解決する
1.指定された名前空間ハンドラーマップをロードすると、抽出された名前空間ハンドラーがキャッシュされてから返されます
public class defaultNamesPaceHandlerResolver {@Override @Nullable public NameSpaceHandler Resolve(String NameSpaceuri){Map <String、Object> HandLermAppings = GethandLermAppings(); // handlermappingsからhandlerorclassnameを抽出しますオブジェクトHandlerorclassname = handlermappings.get(namespaceuri); if(handlerorclassname == null){return null; } else if(handlerorclassname instance of namespacehandler){return(namespacehandler)handlerorclassname; } else {string classname =(string)handlerorclassname; try {class <? if(!namespacehandler.class.isassignablefrom(handlerclass)){newspace [" + namesspaceuri +"の新しいdatalbeanexception( "class [" + classname + "]をスローします。 } //名前空間名に基づいて対応する情報を見つけますnamespacehandler namespacehandler =(namespacehandler)beanutils.instantiateclass(handlerclass); //ハンドラーはnamespacehandler.init()を初期化します。 handlermappings.put(namespaceuri、namespacehandler); namespacehandlerを返します。 } catch(classNotFoundException ex){newspacehandler class [" + className +"] for NameSpace [" + namesSpaceuri +"] found not not "、ex); } catch(linkageError err){newspace [" + classname +"] for namespace [" + namespaceuri +"]:newspacehandler class [" + classname +"]:nemspacehandler class [" + classname +"]:Handlerクラスファイルまたは依存クラスの問題 "、err); }}}}タグ分析
NamesSpaceHandlerをロードした後、BattcnnamesSpaceHandlerが初期化され、BattcnnamesSpaceHandlerもinit()メソッドを呼び出して初期化作業を完了します。したがって、私はこのコードを引き続き実行します: handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));特定のタグソリューション。
public class namespacehandlersupport {@override @nullable public beandefinition parse(element element、parsercontext parsercontext){beandefinitionParser parser = findParserForelement(element、parsercontext); return(parser!= null?parser.parse(element、parsercontext):null); } @Nullable Private BeanDefinitionParser findParserForelement(要素要素、ParserContext ParserContext){//アプリケーション文字列localName in <battcn:application /> .getDelegate()。getLocalName(要素); beandefinitionParser parser = this.parsers.get(localname); if(parser == null){parsercontext.getReaderContext()。fatal( "要素のためのbeandefinitionParser [" + localName + "]"、element); } parserを返します。 }}簡単に言えば、ParsersからApplicationBeanDefinitionParserインスタンスを見つけて、さらなる分析のために独自のドパース方法を呼び出すことです。最後に、それはデフォルトのタグを解析するのと同じルーチンです...
要約します
数回未知の秋、冬、春、夏の後、すべてがあなたが望む方向に従います...
さて、上記はこの記事のコンテンツ全体です。この記事の内容には、すべての人の研究や仕事に特定の参照値があることを願っています。ご質問がある場合は、メッセージを残してコミュニケーションをとることができます。 wulin.comへのご支援ありがとうございます。
何か言って
全文コード:https://gitee.com/battcn/battcn-spring-source/tree/master/chapter2