Die diesmal erwähnte Java -Reflexion beinhaltet viel Code. Da die Reflexion bei der Arbeit häufig verwendet wird, haben wir viele Abstraktionen und Filter zum Code gemacht. Obwohl der Code groß ist, ist er einfach und einfach zu bedienen, und Filter-Plug-Ins sind ebenfalls einfach zu ändern.
Das Folgende ist eine Beschreibung, wo die Reflexion bei der Arbeit leichter zu bedienen ist. Zum Beispiel können Plug-Ins oder Filter, wenn weniger abstrakte Unterklassen vorhanden sind, und die Konfiguration von XML und anderen Strukturen ebenfalls den gleichen Effekt erzielen. Wenn Sie flexibler sein möchten, können Sie es direkt nach dem Hinzufügen von Plug-Ins oder Filtercode-Unterklassen verwenden. Es ist möglicherweise besser, nachzudenken, und alle ererbten Unterklassen werden durch Scannen aller Klassen- oder JAR -Dateien erhalten. Wenn Sie alle Dateien jeden Anruf scannen, wirkt sich dies auf die Leistung aus. Daher wird der Implementierung ein Reflexions -Cache hinzugefügt, um alle Reflexionsergebnisse als Schlüssel für alle Parameter zu zwischenstrahlen, die bei der Erhalt der Reflexionsunterklasse beteiligt sind. Wenn es das nächste Mal der gleiche Schlüssel ist, werden Sie nicht rescan.
Das Codebeispiel lautet wie folgt:
public static void main (String [] args) {// Setzen Sie den Scan-Bereich, der der Ort der Klassendatei sein kann, wie z. Versuchen Sie {// Sie können jedes Mal vollständige Scans in der Debugging -Stufe einstellen // Beans.setDesignTime (true); endgültige Sammlung <string> subtypes = reflectutils.listsubClass (ia.class); // für (endgültige String subtyp: subtypen) {// Was Sie hier erhalten, sind System.out.println (Subtyp); endgültig ia impl = reflectils.initClass (Subtyp, IA.Class); if (null == impl) weiter; // Mit dieser Methode können Sie Operationen auf einheitliche Weise ausführen, impl.print (); }} catch (Ausnahme e) {e.printstacktrace (); }}Code -Ausführungsergebnis:
// Die Datei zwischendurchschnittlich rescaning jedes Mal, wenn die Reflexion aufgerufen wird // Wenn Sie die Datei löschen, wird sie neu gestaltet, wenn die Reflexion erneut aufgerufen wird. Im Allgemeinen wird die Datei gelöscht, wenn im Code Unterklassen enthalten sind. XMLUTILS.READXML -Fehler: ./ configuration.ref (Das System kann die angegebene Datei nicht finden.) Net.simple.reflect.test.bnet.simple.reflect.test.bnet.simple.refect.test.bnet.vetest.vest.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.simple.Stest.Test.Test.Test.Test.Test.Test.Test.Test.Test.Test.Test.Test.Test.Test.Test.Test.Test.Test.Test.Test.Test.Test.Test.Simple hat kann ist
Weitere Informationen finden Sie im Quellcode. Hier sind zwei Kernklassencodes. Quellcodeadresse: https://git.oschina.net/eliyanfei/api_tools
Paket net.simple.reflect; import java.io.file; import Java.io.ioException; import Java.net.jarurlConnection; import Java.net.url; Import Java.net.Urdecoder; Import Java.util.ArrayList; Import Java.util.util.Collection; java.util.linkedhashMap; Import Java.util.List; Import Java.util.map; Import Java.util.Concurrent net.simple.reflect.filter.ipathurlfilter; import net.simple.reflect.filter.isubtypefilter; import net.simple.reflect.filter.itypefilter; import org.w3c.dom.document; [email protected] * 2. November 2016 um 15:23:49 Uhr * */Public Final Class Reflections {private endgültige Sammlung <URL> Pathurls; Private Final Collection <Pathurlfilter> PathurlFilters; private endgültige Sammlung <Itypefilter> Schriftart; privates isuubtypefilter subtypefilter; public reflections () {vortefilters = new ArrayList <Itypefilter> (); pathurlFilters = new ArrayList <ipathurlFilter> (); this.pathurls = classPathHelper.geturlsforcurrentClassPath (); } öffentliche Reflexionen (endgültige Sammlung <URL> pathurls) {this.pathurls = pathurls; vortefilters = new ArrayList <Itypefilter> (); pathurlFilters = new ArrayList <ipathurlFilter> (); } / ** * @param subtypeFilter * Der SubtypeFilter zu festlegen * / public void setSuBTypeFilter (endgültig isuubTypeFilter subtypefilter) {this.subTypeFilter = subtypefilter; } / ** * @return the subtypeFilter * / public isubrefilter getubrefilter () {return subtypefilter; } public Reflections addpatpathurlfilter (endgültig ipathurlfilter pathurlfilter) {if (null == pathurlfilter) return dies; if (! this.pathurlFilters.contains (pathurlFilter)) this.pathurlFilters.add (pathurlfilter); gib dies zurück; } public Reflections addtypeFilter (endgültig itypefilter vortefilter) {if (null == vortefilter) return this; if (! this.typefilters.contains (vortefilter)) this.typefilters.add (vortefilter); gib dies zurück; } private statische endgültige Zeichenfolge histfile = "./configuration.ref"; private Dokument Histome; public collection <string> getuBTypesfast (endgültige Klasse <?> BaseType) {//, endgültige String ... Typenams // FILTER DER PATH, das derzeit endgültig scannen kann, um den endgültigen StringBuilder bufpathsid = new StringBuilder (32) zu scannen; endgültige Karte <Datei, url> fileUrls = new LinkedHasMap <Datei, URL> (8); für (endgültige URL Pathurl: pathurls) {if (! AcceptPathurl (pathurl)) Fortsetzung; Datei Datei = null; try {file = new Datei (urdecoder.decode (pathurl.getFile (), "utf-8")); } catch (endgültige Ausnahme e) {Datei = neue Datei (pathurl.getFile ()); } fileUrls.put (Datei, Pathurl); if (! file.exists ()) // Ist URL -Datei? Ignorieren Sie weiter; bufpathsid.append (file.getName ()). append (Datei.lastModified ()); } Final String domid = Md5.Gethashstring (bufpathsid.toString ()); if (null == histom) seine if (null == histom) seine Domd = w3cutils.Newdom ("r"); Element rootele = histom.getDocumentElement (); if (null == rootele) histom.appendChild (Rootele = histom.createelement ("r")); if (! domid.equals (rootele.getAttribute ("id"))) {rootele.getParentNode (). removeChild (rootele); histom.Appendchild (Rootele = histom.createelement ("r")); Rootele.setattribute ("id", domid); } Finale String baseTypeId = Md5.Gethashstring (BaseType.getName ()); Element Refele = W3Cutils.FirstChildElement (Rootele, "E", "ID", BasetypeId); if (null! endgültige Sammlung <string> result = new ArrayList <string> (valueLes.size ()); für (endgültige Element Valueele: ValueLes) {result.add (neuer String (Base64.DecodeFast (ValueEle.getAttribute ("id"))); } Rückgabeergebnis; } Final ThreadPool <listSuBypes> pool = new ThreadPool <listSuBypes> (); für (endgültige FileKey: FileUrls.keyset ()) {pool.execute (neue ListSuBypes (BaseType, FileKey, FileUrls.get (FileKey))); } try {pool.shutdown (3, TimeUnit.minutes); } catch (endgültige InterruptedException e) {e.printstacktrace (); // für Debug} endgültige Sammlung <string> result = new ArrayList <string> (); für (endgültige ListSuBypes -Aufgabe: pool.getThreadrunables ()) {result.addall (task.result); } Refele = w3cutils.addele (Rootele, "e"); Refele.SetatTribute ("ID", BaSetypeId); für (endgültige Zeichenfolge ITM: Ergebnis) {w3cutils.addele (Refele, "f"). setAttribute ("id", Base64.EncodetoString (itm.getBytes (), false)); } try {w3cutils.writexmldocument (histfile, histom); } catch (endgültige Ausnahme E) {} Rückgabeergebnis; } / ** * @see {@link reflectUtils#CreateSharedReflections (String ...)} * @see {@link reflectUtils#setSharedReflections (Reflexionen)} * @see {@link reflectils#listsubclass (class) @param basetype * @return * / Public Collection <Spublics -Kollektion <- und Publics -Kollektions <Spublic <Spublic <Spublic <Spublic <Spublic <Spublic <Spublic & sub2; typeNames) {// Final ThreadPool <listSuBypes> pool = new ThreadPool <listSuBypes> (); für (endgültige URL Pathurl: pathurls) {if (! AcceptPathurl (pathurl)) Fortsetzung; Datei Datei = null; try {file = new Datei (urdecoder.decode (pathurl.getFile (), "utf-8")); } catch (endgültige Ausnahme e) {Datei = neue Datei (pathurl.getFile ()); } pool.execute (neue ListsuBypes (BaseType, Datei, Pathurl, Typenamen)); } try {pool.shutdown (3, TimeUnit.minutes); } catch (endgültige InterruptedException e) {e.printstacktrace (); // für Debug} endgültige Sammlung <string> result = new ArrayList <string> (); für (endgültige ListSuBypes -Aufgabe: pool.getThreadrunables ()) {result.addall (task.result); } Rückgabeergebnis; } class listSuBypes implementiert runnable {endgültige Dateidatei; endgültige Klasse <?> Basetyp; endgültige URL Pathurl; endgültige Zeichenfolge [] Typenamen; public ListSuBypes (endgültige Klasse <?> BaseType, endgültige Dateidatei, endgültige URL -Pathurl, endgültige Zeichenfolge ... typenames) {this.basetype = BaseType; this.file = Datei; this.pathurl = pathurl; this.typenamen = typenamen; } Collection <string> result = new ArrayList <string> (4); @Override public void run () {if (file.isdirectory ()) {listSuBTypesfromDirectory (Datei, BaseType, Pathurl, Datei, Ergebnis, TypeNamen); } else listSuBypesFromjar (BaseType, Pathurl, Ergebnis, Typenamen); }} / ** * @param BaseType * @param pathurl * @param result if (null == Dateien) Dateien = new Datei [] {}; String ClazzPath; endgültig int -basiertes is -basiert -Verzeichnis.getabsolutepath (). Länge () + 1; für (endgültige Dateidatei: Dateien) {if (file.isdirectory ()) {listSuBTypesFromDirectory (basiertanermaßen, baSetype, pathurl, Datei, Ergebnis, TypeNamen); } else {clazzPath = file.getabsolutepath (). substring (basierend); clazzPath = clazzPath.replace ('//', '/'); DotypesFilter (Basetyp, Pathurl, Ergebnis, ClazzPath, Typenamen); }}} / ** * @param BaseType * @param pathurl * @param result * / public void ListSuBTypesFromjar (endgültige Klasse <?> BaseType, url pathurl, endgültige Sammlung <string> Ergebnis, endgültige String ... Typenamen) {Try {// Es funktioniert nicht in der Datei. Jarfile jarfile = null; try {if ("file" .equals (pathurl.getProtocol ()) pathUrl = new URL ("jar:" + pathurl.toexternalForm () + "!/"); jarfile = ((jarurlConnection) pathurl.openconnection ()). getJarfile (); } catch (endgültige Ausnahme E) {Final String filepath = pathurl.getFile (); // if auf der Win -Plattform if (filepath.indexof (':')! } if (null == jarfile) jarfile = new Jarfile (filepath); } endgültige Aufzählung <Jarentry> e = jarfile.entries (); Zipentry -Eintrag; while (e.hasmoreElements ()) {Eintrag = e.NextElement (); DotypesFilter (BaseType, Pathurl, Ergebnis, Eintrag.getName (), Typenamen); }} catch (endgültig ioException ioex) {}} private void dotypesFilter (endgültige Klasse <?> BaseType, endgültige URL -Pathurl, endgültige Sammlung <string> Ergebnis, endgültiger String ClazzPath, endgültige String ... Typenamen) {if (! ClazzPath.endswith (". Klasse") return; endgültig int lastdotidx = clazzPath.lastIndexof ('.'); if (-1 == lastdotidx) return; Final String typedef = clazzPath.substring (0, lastdotidx) .Replace ('/', '.'); if (null! = typeNames && typenames.length> 0) {Final int lastdot = typedef.lastIndexof ('.'); if (lastdot == -1) return; Final String typeName = typedef.substring (lastdot + 1); boolean withliked = false; für (endgültige String tmptypeName: typename) {if (! typename.contains (tmptypeName)) Fortsetzung; WithLiked = True; brechen; } if (withliked == false) return; } if (this.typefilters.isempty ()) {if (null == this.subTypeFilter || this.subTypeFilter.accept (Basetype, pathurl, clazzPath)) result.add (typedef); } else {für (endgültig itypefilter vortefilter: this.typefilters) {if (! vortefilter.accept (clazzPath)) Fortsetzung; if (null == this.subTypeFilter || this.subTypefilter.accept (Basetyp, Pathurl, ClazzPath)) result.add (typedef); }}} / ** * @param pathurl * @return * / private boolean AcceptPathurl (endgültige URL pathurl) {if (this.pathUrlFilters.iseMpty ()) return true; für (endgültig ipathurlfilter pathurlfilter: this.pathurlFilters) {if (pathurlfilter.accept (pathurl)) return true; } return false; }}
Paket net.simple.reflect; import java.beans.beans; import java.io.file; import Java.io.ioxception; import Java.io.unsupportendenCodingException; Import Java.net.jarurlconnection; Java.util.Collection; Import Java.util.Collections; Import Java.util.Enumeration; Import Java.util.List; Import Java.util.jar.jarentry; Import Java.util.jar.jarfile; Import. net.simple.reflect.filter.sAmplesubinstanceFilter; net.simple.reflect.filter.typefilter; "$ {"; public static final String var_end_flag = "}"; private statische Reflexionen SharedReflexionen; statische endgültige Sammlung <string> emp_coll = collectionss.EmptyList (); public static endgültige void CreatesharedReflections (endgültige Zeichenfolge ... Filterexte) {endgültige Reflexionen refs = new Reflections (); Refs.AddpatheUrlFilter (neuer PathurlFilter (Filterexte)); // Refs.addTypeFilter (STIPFILTER.DEFAULT); Refs.SetsuBypeFilter (ProbensubinstanceFilter.Default); Reflektils.setsharedReflections (Refs); } /*** Diese Methode wird verwendet, um ein gemeinsam genutztes Zirkulationswerkzeug zu binden. * @Param SharedReflections */ Public Static Final Void SetSharedReflections (endgültige Reflexionen SharedReflections) {reflectutils.sharedReflections = SharedReflections; } /*** Bevor Sie diese Methode aufrufen, müssen Sie zunächst das Umfangswerkzeug für gemeinsam genutzte Typ festlegen. Referenz: {@link #setSharedReflections (Reflexionen)}, * Diese Methode macht es hauptsächlich bequemer, die angegebene Klasse zu implementieren, */ public statische endgültige Sammlung <string> ListSubClass (endgültige Klasse <?> BaseType, endgültige String ... Typenams) {// if (null == sharedReflections) return emp_coll; // Da in der Anrufstufe neue Implementierungen der Unterklasse hinzugefügt werden können, ist es erforderlich, jedes Mal zu rescan. Nur wenn das Produkt veröffentlicht wird, wird die Methode zum Speichern von Datensätzen verwendet, um die Startgeschwindigkeit zu verbessern. Beancens.isdesignTime () zurückgeben? SharedReflections.GetSuBypes (BaseType, TypeNames): SharedReflections.GetSubTypesfast (BaseType); } öffentliche statische Liste <Klasse <? >> ListClassOfPackage (endgültige Klasse <?> cType, endgültige String -Erweiterung) {endgültige Liste <Klasse <? >> result = new ArrayList <Klasse <>> (); endgültige Liste <string> cpath = reflectUtils.ListClasscanonicalNameOfPackage (CTYPE, Erweiterung); für (endgültiger String -Pfad: cpath) {try {result.add (class.forname (Pfad, false, Thread.currentThread (). getContextClassloader ())); } catch (endgültige Ausnahme E) {// Ignorieren}} Rückgabeergebnis; } public static list <string> listClasscanonicalNameOfpackage (endgültige Klasse <?> Clazz, endgültige String -Erweiterung) {return reflectUtils.ListnameOfpackage (Clazz, Erweiterung, True); } public static list <string> listClassNameofpackage (endgültige Klasse <?> Clazz, endgültige String -Erweiterung) {return reflectUtils.listnameOfpackage (Clazz, Erweiterung, False); } public static list <string> listNameofpackage (endgültige Klasse <?> Clazz, endgültige String -Erweiterung, endgültig boolean fullpkgname) {return reflectutils.listnameofpackage (clazz.getName (). ersetzen ('. } public static list <string> listNameOfpackage (endgültiger String clazzpkg, endgültige String -Erweiterung, endgültiger boolean fullpkgname) {endgültige Liste <string> result = new ArrayList <string> (); endgültig stringBuffer pkgbuf = new StringBuffer (clazzpkg); if (pkgbuf.charat (0)! = '/') pkgbuf.insert (0, '/'); endgültige URL -URLPath = reflectutils.class.getResource (pkgbuf.tostring ()); if (null == urlPath) Rückgabeergebnis; String checkEdextenion = Erweiterung; if (! extenion.endswith (". Klasse") checkEdextenion = extension + ".class"; if (pkgbuf.toString (). Endswith (". Klasse"))) pkgbuf.delete (pkgbuf.lastindexof ("/"), pkgbuf.length ()); pkgbuf.deletecharat (0); final StringBuffer FileURL = new StringBuffer (); try {FileUrl.Append (urldecoder.decode (urlpath.toexternalForm (), "utf-8")); } catch (endgültige nicht unterstützteEcodingException e1) {fileurl.append (urlPath.toexternalForm ()); } if (FileUrl.toString (). startsWith ("Datei:") {FileUrl.delete (0, 5); // Datei löschen: Flag if (FileUrl.indexof (")! 8); ReflectUtils.dolistNameofpackageIntirectory (neue Datei (basiert), neue Datei (basiert), Ergebnis, pkgbuf.toString (), checkEdextenion, fullpkgname); } else {reflectils.dolistNameofpackageInjar (UrlPath, UrlPath, Ergebnis, pkgbuf.toString (), checkEdextenion, fullpkgname); } Rückgabeergebnis; } / *** / private statische void dolistNameofpackageInjar (endgültige URL -Basis, endgültige URL -URLPath, endgültige Liste <string> Ergebnis, endgültige String clazzpkg, endgültige String -Erweiterung, endgültiger boolean fullpkgname) {try {// Es funktioniert nicht mit dem Dateisystem. endgültige jarurlConnection conn = (jarurlConnection) urlPath.OpenConnection (); endgültig jarfile jFile = conn.getJarfile (); endgültige Aufzählung <Jarentry> e = JFILE.ENTRIES (); Zipentry -Eintrag; String -Eintragsname; while (e.hasmoreElements ()) {Eintrag = e.NextElement (); EintragName = Eintrag.getName (); if (EintragName.StartsWith (Clazzpkg) && Eintragenname.endswith (extenion)) {if (fullpkgname) result.add (Eintragsname.substring (0, Eintragsname.Lastindexof ('.')). sonst result.add (EntryName.substring (EintragName.LastIndexof ('/') + 1, Eintragsname.lastIndexof ('.'))); }}} catch (endgültige IOException ioex) {}} private statische void dolistNameOfpackageInDirectory (endgültige Dateibasisanlage, endgültige Dateiverzeichnis, endgültige Liste <string> Ergebnis, endgültige String -String -Clazzpkg, endgültige String -Erweiterung, endgültige boolean fullpkgname) {] Dateien = DIRECTORY = DIRECTORY.LISTFILES.LISTFILES (); if (null == Dateien) Dateien = new Datei [] {}; String ClazzPath; endgültig int -basiertes is -basiert -Verzeichnis.getabsolutepath (). Länge () + 1; für (endgültige Dateidatei: Dateien) {if (file.isdirectory ()) {reflectils.dolistNameOfpackageInDirectory (basiertanlösend, Datei, Ergebnis, Clazzpkg, Erweiterung, Fullpkgname); } else {if (! file.getName (). Endswith (extenion)) Fortsetzung; if (fullpkgname) {clazzPath = file.getabsolutepath (). substring (basiertesirlen); clazzPath = clazzPath.substring (0, clazzPath.length () - 6); result.add (clazzPath.replace (Datei.SeparatorChar, '.')); } else {result.add (file.getName (). substring (0, file.getName (). Länge () - 6)); }}}} public static final <t> t initClass (endgültige String -Implklasse, endgültige Klasse <T> tType) {return reflectUtils.initClass (Implclass, type, true); } public static Final <T> T initClass (endgültige String -Implklasse, endgültige Klasse <T> tType, endgültig boolean doInit) {try {endgültig Objekt = class.Forname (Implclass, doInit, Thread.currentThread (). getContextClassloader (). return type.cast (Objekt); } catch (letztes Throwable E) {return null; }}} Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird für das Lernen aller hilfreich sein und ich hoffe, jeder wird Wulin.com mehr unterstützen.