Kata pengantar
Di bagian sebelumnya Dekripsi Spring - Analisis tag default, kami fokus pada menganalisis bagaimana pegas mem -parsing tag default. Jadi bab ini terus menjelaskan parsing label, fokus pada cara menguraikan tag khusus. Tanpa basa -basi lagi, mari kita lihat perkenalan yang terperinci.
Tag khusus
Sebelum menjelaskan analisis tag khusus, silakan lihat cara menyesuaikan tag
Tentukan file XSD
Tentukan file XSD untuk menjelaskan konten komponen
<? Xml Version = "1.0" encoding = "utf-8"?> <xsd: schema xmlns = "http://www.battcn.com/schema/battcn" xmlns: xsd = "http://www.w3.org/2001/ xmlns:beans="http://www.springframework.org/schema/beans" targetNamespace="http://www.battcn.com/schema/battcn" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xsd:import namespace="http://www.springframework.org/schema/beans" /> <xsd:element name="application"> <xsd:complexType> <xsd:complexContent> <xsd:extension base="beans:identifiedType"> <xsd:attribute name="name" type="xsd:string" use="required"/> </xsd: Extension> </xsd: ComplexContent> </xsd: Complextype> </xsd: Element> </xsd: Schema>
Tentukan aturan parsing
1. Buat kelas untuk mengimplementasikan antarmuka BeandefinitionParser (juga dapat mewarisi kelas yang disediakan oleh Spring) untuk menguraikan definisi dan definisi komponen dalam file XSD.
Application PublicBeandefinitionParser memperluas AbstractSinglebeandefinitionParser {@Override class lindung getBeAnclass (elemen elemen) {// Jenis objek yang diterima adalah seperti: string name = (string) context.getBean ("battcn"); return string.class; } @Override Protected void doparse (elemen elemen, beandefinitionBuilder bean) {// atribut nama yang ditentukan dalam xsd string name = element.getAttribute ("name"); bean.addconstructorArgvalue (nama); }}Berikut ini adalah ApplicationBeandefinitionParser yang mewarisi AbstractSinglebeandefinitionParser (adalah subclass dari BeandefinitionParser). Fokusnya adalah untuk mengganti doparse, parse tag XML di dalamnya, dan kemudian menyuntikkan nilai parsed (levin) ke dalam konstruktor.
2. Buat kelas untuk mewarisi kelas abstrak namespaceLersupport
Kelas Publik BattcnNamespaceHandler memperluas namespaceHandlersupport {@Override public void init () {registerBeandefinitionParser ("Application", ApplicationBeandEfinitionParser ()); }} Fungsi BattcnNamespaceHandler sangat sederhana, yaitu untuk memberi tahu Container Spring bahwa tag <battcn:application /> harus diuraikan oleh parser tersebut (di sini kami disesuaikan: ApplicationBeandefinitionParser), yang bertanggung jawab untuk mendaftarkan komponen ke wadah pegas.
3. Tulis Spring.Handlers dan Spring.schemas Files
Direktori tempat file disimpan terletak di Sumber Daya/Meta-Inf/Nama File
Spring.Handlers
http/: //www.battcn.com/schema/battcn=com.battcn.handler.battcnnamespaceAndler
Spring.schemas
http/: //www.battcn.com/schema/battcn.xsd=battcn.xsd
4. Gunakan tag khusus
Menyatakan file bean.xml, didefinisikan sebagai berikut
<? XML Versi = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmls xmlns: battcn = "http://www.battcn.com/schema/battcn" xsi: schemalocation = "http://www.springframework.org/schema/beans http:/wwww.springframework http://www.battcn.com/schema/battcn http://www.battcn.com/schema/battcn.xsd "> <battcn: aplikasi id =" battcn "name =" levin "/> </beans>
Buat kelas tes. Jika Anda melihat kata Levin output konsol, itu berarti label kustom normal.
aplikasi kelas publik {public static void main (string [] args) {applicationContext context = new ClassPathXMLapPlicationContext ("bean.xml"); String name = (string) context.getBean ("Battcn"); System.out.println (nama); }}5. seperti yang ditunjukkan pada gambar
Analisis Kode Sumber
Portal Resolusi Tag Kustom
Kelas Publik BeandefinitionParserDelegate {@nullable Public Beandefinition Parsecustomelement (Element Ele, @Nullable Beandefinition containsbd) {// Dapatkan alamat namespace http://www.battcn.com/schema namespace namespace namespace namespace; if (namespaceuri == null) {return null; } // namespaceHandler adalah aplikasi yang terdaftar di BattcnNamespace -NamespaceShandler Handler yang disesuaikan = this.readerContext.getNamespaceLerRerRerver (). Resolve (namespaceuri); if (handler == null) {error ("Tidak dapat menemukan spring namespaceHandler untuk skema xml namespace [" + namespaceuri + "]", ele); kembali nol; } return handler.parse (ele, parsercontext baru (this.readerContext, this, containingBd)); }} Seperti aturan resolusi tag default, namespace diperoleh melalui getNamespaceURI(Node node) . Jadi di mana this.readerContext.getNamespaceHandlerResolver() diperoleh? Kami melacak kode dan kami dapat menemukan bahwa ketika proyek dimulai, semua konten file meta-inf/spring. Penanganan akan diuraikan dalam xmlbeandefinitionReader dan disimpan di handlermappers (concurrenthashmap). Ketika resolve(namespaceUri) dipanggil untuk memeriksa, konten yang di -cache akan diekstraksi untuk perbandingan.
Kelas Publik XMLBeAnDefinitionReader {public namespaceAdlerResolver getNamespaceHandLerResolver () {if (this.namespaceLerResolver == null) {this.namespaceLerResolver = createDefaultNeSpaceLerReRsolver (); } kembalikan this.namespaceHandLerResolver; }}menyelesaikan
1. Muat peta namespace -namespace yang ditentukan, dan namespace -namespaceHandler diekstraksi di -cache, dan kemudian kembali
Public Class DefaultNAspaceHandLerReSolver {@Override @nullable Public namespaceHandler Resolve (String namespaceuri) {MAP <String, Object> HandlermAppings = getHandLermAppings (); // ekstrak handlerorclassname dari handlermappings objek handlerorclassname = handlermappings.get (namespaceuri); if (handlerorclassname == null) {return null; } else if (handlerorclassname instance dari namespaceHandler) {return (namespaceHandler) handlerorclassname; } else {string classname = (string) handlerorclassname; coba {class <?> handlerclass = classutils.forname (className, this.classloader); if (! namespaceHandler.class.isassignableFrom (handlerclass)) {throw new fatalbeanException ("class [" + className + "] untuk namespace [" + namespaceuri + "] tidak mengimplementasikan [" + namespaceHandler.class.getName () "]; } // Temukan informasi yang sesuai berdasarkan namespace namespaceHandler namespaceHandler = (namespaceHandler) beanutils.instantiateclass (handlerclass); // pawang menginisialisasi namespaceHandler.init (); handlermappings.put (namespaceuri, namespaceHandler); return namespaceHandler; } catch (ClassNotFoundException ex) {Throw New FatalbeanException ("NamespaceHandler Class [" + ClassName + "] untuk namespace [" + namespaceuri + "] tidak ditemukan", ex); } catch (LinkageError err) {throw new fatalbeanException ("kelas namespaceHandler yang tidak valid [" + className + "] untuk namespace [" + namespaceuri + "]: Masalah dengan file kelas pawang atau kelas dependen", err); }}}}Analisis tag
Setelah memuat NamespaceHandler, BattcnnamespaceSandler telah diinisialisasi, dan BattcnnamespaceHandler juga memanggil metode init() untuk menyelesaikan pekerjaan inisialisasi. Oleh karena itu, saya akan terus menjalankan kode ini: handler.parse(ele, new ParserContext(this.readerContext, this, containingBd)); solusi tag tertentu.
kelas publik namespaceHandLersupport {@Override @nullable Public Beandefinition Parse (Elemen Elemen, Parsercontext Parsercontext) {BeandefinitionParser parser = findParserForElement (Elemen, Parsercontext); return (parser! = null? parser.parse (elemen, parsercontext): null); } @Nullable Private BeandefinitionParser findParserForElement (elemen elemen, parsercontext parsercontext) {// parse aplikasi string localname di <battcn: application /> .getDelegate (). GetLocalName (elemen); BeandefinitionParser parser = this.parsers.get (localname); if (parser == null) {parsercontext.getreaderContext (). fatal ("tidak dapat locale beandefinitionParser untuk elemen [" + localname + "]", elemen); } return parser; }}Sederhananya, itu adalah untuk menemukan contoh aplikasi danfinitionParser dari parser dan memanggil metode doparse sendiri untuk analisis lebih lanjut. Akhirnya, ini adalah rutin yang sama untuk parsing tag default ...
Meringkaskan
Setelah beberapa musim gugur, musim dingin, musim semi, dan musim panas yang tidak diketahui, semuanya akan mengikuti arah yang Anda inginkan ...
Oke, di atas adalah seluruh konten artikel ini. Saya berharap konten artikel ini memiliki nilai referensi tertentu untuk studi atau pekerjaan semua orang. Jika Anda memiliki pertanyaan, Anda dapat meninggalkan pesan untuk berkomunikasi. Terima kasih atas dukungan Anda ke wulin.com.
Katakan sesuatu
Kode Teks Lengkap: https://gitee.com/battcn/battcn-spring-source/tree/master/chapter2