La réflexion Java mentionnée que cette fois implique beaucoup de code. Parce que la réflexion est souvent utilisée dans le travail, nous avons fait beaucoup d'abstractions et de filtres au code. Bien que le code soit grand, il est simple et facile à utiliser et les plug-ins filtrants sont également faciles à modifier.
Ce qui suit est une description de l'endroit où la réflexion est plus facile à utiliser au travail. Par exemple, les plug-ins ou les filtres, s'il y a moins de sous-classes abstraites, les configurer en XML et dans d'autres structures peuvent également obtenir le même effet. Si vous souhaitez être plus flexible, vous pouvez l'utiliser directement après avoir ajouté des plug-ins ou des sous-classes de code filtre. Il peut être préférable de réfléchir et toutes les sous-classes héritées sont obtenues en scannant tous les fichiers de classe ou de jar. Si vous analysez tous les fichiers à chaque appel, cela affectera les performances. Par conséquent, un cache de réflexion est ajouté à l'implémentation pour mettre en cache tous les résultats de réflexion comme clé pour tous les paramètres impliqués dans l'obtention de la sous-classe de réflexion. S'il s'agit de la même clé la prochaine fois, vous ne ren sauverez pas.
L'exemple de code est le suivant:
public static void main (String [] args) {// Définit la plage de numérisation, qui peut être l'emplacement du fichier de classe, tel que l'emplacement sous bin, ou le début de MySQL ou la fin de MySQL, // set "" pour scanner tout, il y a du temps à faire des réflexions. essayez {// vous pouvez définir des analyses complètes à chaque fois dans l'étape de débogage // beans.setDesignTime (true); Sous-types de collection finale <string> = reflents.listsubclass (ia.class); // for (Final String Souspe: sous-types) {// ce que vous obtenez ici sont System.out.println (sous-type); Final Ia Imp = ReflectUtils.InitClass (sous-type, ia.class); si (null == impl) continue; // Grâce à cette méthode, vous pouvez effectuer des opérations de manière unifiée, imp.print (); }} catch (exception e) {e.printStackTrace (); }}Résultat de l'exécution du code:
// Cachez le fichier pour éviter le annulation à chaque fois que la réflexion est appelée // Si vous supprimez le fichier, il sera sauvé lorsque la réflexion sera à nouveau appelée. Généralement, le fichier sera supprimé lorsqu'il y aura des sous-classes dans le code. Xmlutils.readxml défaillance: ./ configuration.ref (le système ne peut pas trouver le fichier spécifié.) Net.simple.reflect.test.bnet.simple.reflect.test.bnet.simple.reflect.test.bnet.simple.reflect.test.dnet.simple.reflect.test.v
Pour plus de détails, veuillez consulter le code source. Voici deux codes de classes de base. Adresse du code source: https://git.oschina.net/eliyanfei/api_tools
package net.simple.reflect; import java.io.file; import java.io.ioException; import java.net.jarurlconnection; import java.net.url; import java.net.urldecoder; import java.util.arraylist; import java.util.collection; import java.util.enumation; import; java.util.linkedhashmap; import java.util.list; import java.util.map; import java.util.concurrent.titt; net.simple.reflect.filter.ipathurlfilter; import net.simple.reflect.filter.isubtypefilter; import net.simple.reflect.filter.itypefilter; import org.w3c.dom.document; import org.w3c.dom.element; / ** * * @author li yanfei * @email; [email protected] * 2 novembre 2016 à 15:23:49 PM * * / Réflexions de classe finale publique {Collection finale privée <URL> Pathurls; Collection finale privée <IpathurlFilter> PathurlFilters; Collection finale privée <ityPeFilter> Typefilters de type; Sous-TypeFilter ISUBTypeFilter privé; Public Reflections () {typeFilters = new ArrayList <ityPeFilter> (); pathurlFilters = new ArrayList <ipathurlFilter> (); this.pathurls = classpathhelper.getUrlsforcurrentClassPath (); } Réflexions publiques (collection finale <URL> Pathurls) {this.pathurls = pathurls; typeFilters = new ArrayList <ityPeFilter> (); pathurlFilters = new ArrayList <ipathurlFilter> (); } / ** * @Param SouspeFilter * Le sous-TypeFilter à définir * / public void setSubTypeFilter (Final ISUBTypeFilter sous-TypeFilter) {this.subTypeFilter = SousPeFilter; } / ** * @return le sous-type defilter * / public ISUBTypeFilter getSubTypeFilter () {return SubTypeFilter; } Réflexions publiques addPathurlFilter (final ipathurlfilter pathurlfilter) {if (null == pathurlfilter) renvoie ceci; if (! this.pathurlfilters.contains (pathurlfilter)) this.pathurlfilters.add (pathurlfilter); retourner ceci; } Public Reflections addTypeFilter (final ityPeFilter typeFilter) {if (null == typeFilter) renvoie ceci; if (! this.typefilters.contains (typefilter)) this.typefilters.add (typeFilter); retourner ceci; } chaîne finale statique privée histfile = "./configuration.ref"; Histance de documents privés; Collection publique <string> getSubTypesFast (Final Class <?> Basetype) {//, Final String ... TYPENAMES // Filtrez d'abord le chemin actuellement autorisé à scanner Final StringBuilder bufPathSid = new StringBuilder (32); Map final <fichier, url> fileUrls = new LinkedHashmap <file, url> (8); pour (URL final Pathurl: Pathurls) {if (! AcceptPathurl (pathurl)) continue; Fichier fichier = null; try {file = new File (urlDEcoder.decode (pathurl.getFile (), "utf-8")); } catch (exception finale e) {file = new File (pathurl.getFile ()); } fileUrls.put (fichier, pathurl); if (! file.exists ()) // Le fichier d'URL est-il contenue; bufpathSid.append (file.getName ()). APPEND (file.lastmodified ()); } Final String Domid = MD5.GETHASHSTRING (bufPathSid.ToString ()); if (null == histance) Hisdom = w3cutils.readxml (histfile); if (null == histance) Hisdom = w3cutils.newdom ("r"); Élément rootelele = histance.getDocumentElement (); if (null == roottele) Histdom.ApendChild (rootEle = Histdom.CreateElement ("r")); if (! Domid.equals (rootele.getAttribute ("id"))) {rootEle.GetParentNode (). ReopoveChild (rootEle); Histance.ApendChild (rootEle = Histance.CreateElement ("r")); rootEle.SetAttribute ("id", domind); } Final String BasetypeId = md5.GethashString (basetype.getName ()); Element Refele = W3cutils.FirstChildElement (Rootele, "E", "ID", BasetypeID); if (null! = Refele) {final list <element> valueleles = w3cutils.childElementList (Refele, "f"); Collection finale <string> result = new ArrayList <string> (valueLes.size ()); for (final element valulele: valueleles) {result.add (new String (base64.decodeFast (valuelele.getAttribute ("id")))); } Retour Résultat; } Final Threadpool <SistSubTypes> pool = new Threadpool <SistSubTypes> (); pour (File File FileKey: fileUrls.KeySet ()) {pool.execute (new ListSubTypes (Basetype, fileKey, fileUrls.get (fileKey))); } essayez {pool.shutdown (3, timeUnit.Minutes); } catch (final InterruptedException e) {e.printStackTrace (); // pour Debug} Collection finale <string> result = new ArrayList <string> (); pour (final listSubTypes tâche: pool.getThreadrunables ()) {result.addall (task.result); } Refele = w3cutils.addele (rootlele, "e"); RefEle.SetAttribute ("ID", BasetypeID); for (final String itm: result) {w3cutils.addele (Refele, "f"). setAttribute ("id", base64.encodetoString (itm.getBytes (), false)); } try {w3cutils.writexmldocument (histfile, histance); } catch (Exception finale e) {} Retour Result; } / ** * @see {@Link ReflectUtils # CreateSharedRefections (String ...)} * @SeE {@Link RefleftUtils # SetSharedReflections (Reflections)} * @See {@Link RefleftUtils # ListSubClass (class)} * @Param Basetype * @return * / public Collection <String> Get typEnames) {// Final Threadpool <SistSubTypes> pool = new Threadpool <SistSubTypes> (); pour (URL final Pathurl: Pathurls) {if (! AcceptPathurl (pathurl)) continue; Fichier fichier = null; try {file = new File (urlDEcoder.decode (pathurl.getFile (), "utf-8")); } catch (exception finale e) {file = new File (pathurl.getFile ()); } pool.execute (new ListSubTypes (Basetype, fichier, pathurl, typenames)); } essayez {pool.shutdown (3, timeUnit.Minutes); } catch (final InterruptedException e) {e.printStackTrace (); // pour Debug} Collection finale <string> result = new ArrayList <string> (); pour (final listSubTypes tâche: pool.getThreadrunables ()) {result.addall (task.result); } Retour Résultat; } classe ListSubTypes implémente Runnable {File File; Classe finale <?> Basetype; Pathurl d'URL final; String final [] TYPENAMES; public listSubTypes (Final Class <?> Basetype, fichier final Fichier, URL Final Pathurl, chaîne finale ... TynEnames) {this.basetype = basetype; this.file = fichier; this.pathurl = pathurl; this.Typenames = typenames; } Collection <string> result = new ArrayList <string> (4); @Override public void run () {if (file.isDirectory ()) {listSubTypesFromDirectory (fichier, basetype, pathurl, fichier, result, typenames); } else listSubTyPesFromjar (Basetype, Pathurl, result, typenames); }} / ** * @param Basetype * @param pathurl * @param résultat * / public void listubtypesFromDirectory (fichier final BasedIrrectory, classe finale <?> Basetype, finaS, URL Pathurl, fichier final Directory.ListFiles (String> Result, final string ... typenames) {file [] fileS = Directory.ListFiles (); if (null == files) files = new File [] {}; String Clazzpath; Final int-basaseLirLlen = basaseDirectory.getAbsoluTepath (). Length () + 1; pour (fichier final Fichier: fichiers) {if (file.isDirectory ()) {listSubTypesFromDirectory (basaseDirectory, Basetype, pathurl, file, result, typenames); } else {ClazzPath = file.getAbsolutepath (). substring (basé-basé); CllazzPath = ClazzPath.replace ('//', '/'); dotypesFilter (Basetype, Pathurl, Result, ClazzPath, Tynenames); }}} / ** * @param Basetype * @param pathurl * @param résultat * / public void lisSubTypesFromjar (Final class <?> Basetype, url pathurl, final collection <string> result, final String ... typEname) {try {// Il ne fonctionne pas avec le système de fichiers: nous devons // être dans le cas d'un package contenu dans un jar. Jarfile jarfile = null; essayez {if ("file" .equals (pathurl.getprotocol ())) pathurl = new url ("jar:" + pathurl.toexternalform () + "! /"); JarFile = ((JarurlConnection) Pathurl.OpenConnection ()). GetJarFile (); } catch (exception finale e) {final string filepath = pathurl.getFile (); // if on win plateforme if (filepath.indexof (':')! = -1) {if (pathurl.getFile (). charat (0) == '/') jarfile = new Jarfile (filepath.substring (1)); } if (null == jarfile) jarfile = new Jarfile (filepath); } énumération finale <Jarentry> e = jarfile.entries (); Entrée de ziperie; while (e.hasmoreElements ()) {entry = e.NextElement (); dotyPesFilter (Basetype, pathurl, result, entry.getName (), typenames); }} catch (final ioException ioEx) {}} private void dotypesFilter (classe finale <?> Basetype, Url Pathurl final, collection finale <string> result, final string cllazzPath, final String ... typenames) {if (! ClazzPath.endswith (". Class")) retour; Final int lastDotidx = CllazzPath.LastIndexof ('.'); if (-1 == LastDotidx) return; String final typedef = ClazzPath.Substring (0, lastDotidx) .replace ('/', '.'); if (null! = typenames && typenames.length> 0) {final int lastdot = typedef.lastIndexof ('.'); if (lastDot == -1) return; chaîne finale typename = typedef.substring (lastDot + 1); booléen withliked = false; for (final String tmpTyPename: typenames) {if (! typename.Contains (tmpTyPename)) Continuer; withliked = true; casser; } if (withliked == false) return; } if (this.typefilters.isempty ()) {if (null == this.subTypeFilter || this.subtypefilter.accept (basetype, pathurl, cllazzpath)) result.add (typedef); } else {for (final ityPeFilter TypeFilter: this.typeFilters) {if (! typeFilter.Accept (CllazzPath)) continue; if (null == this.subTypeFilter || this.subtypefilter.accept (basetype, pathurl, cllazzpath)) result.add (typedef); }}} / ** * @param pathurl * @return * / private boolean acceptPathurl (final url pathurl) {if (this.pathurlfilters.isempty ()) return true; for (final ipathurlfilter pathurlfilter: this.pathurlfilters) {if (pathurlfilter.accept (pathurl)) return true; } return false; }}
package net.simple.reflect; import java.beans.beans; importer java.io.file; import java.io.ioexception; import java.io.unsuppordencodingException; import java.net.urldecoder; import java.net.url; import java.net.urldeccoder; import java.util.arl; import; 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 java.util.zip.zipentry; import ne.simple.reflect.filter net.simple.reflect.filter.samplesBinstanceFilter; import net.simple.reflect.filter.typefilter; / ** * * @author li yanfei * @email [email protected] * 2 novembre 2016 à 3:24:02 PM * * / public final reflev "$ {"; chaîne finale statique publique var_end_flag = "}"; Réflexions statiques privées SharedReflections; Collection finale statique <string> emp_coll = collections.emptyList (); public static final void createShareDrefections (final string ... filteRexts) {final Reflections Refs = new Reflections (); refs.adddpathurlfilter (new PathurlFilter (filterExts)); // refs.AddTypeFilter (typeFilter.default); RefS.SetSubTypeFilter (SamplesBinstanceFilter.Default); ReflectUtils.setSharedReflections (Refs); } / ** * Cette méthode est utilisée pour lier un outil de circulation de type partagé commun. * @param SharedReflections * / public static final void SetSharedRefections (réflexions finales SharedReflections) {ReflectUtils.SharedReflections = SharedReflections; } / ** * Avant d'appeler cette méthode, vous devez d'abord définir l'outil circonférentiel de type partagé. Référence: {@link #setSharedReflections (Reflections)}, * Cette méthode rend principalement plus pratique d'implémenter la classe donnée, * / public static final Collection <string> listSubClass (class final <?> Basetype, final String ... typenames) {// if (null == sharedReflections) return emp_coll; // Étant donné que de nouvelles implémentations de sous-classe peuvent être ajoutées au stade de l'appel, il est nécessaire de sauver à chaque fois. Ce n'est que lorsque le produit est publié que la méthode d'économie d'enregistrement est utilisée pour améliorer la vitesse de démarrage. return beans.isdesignTime ()? SharedReflections.getSubTypes (Basetype, typenames): sharedReflections.getSubTypesFast (Basetype); } public static list <class <? >> listClassOfPackage (final class <?> ctype, extension finale de chaîne) {Liste finale <class <? >> result = new ArrayList <class <? >> (); Liste finale <string> cpath = reflents.listClassCanonicalNameOfPackage (ctype, extension); pour (Final String Path: cPath) {try {result.add (class.forname (path, false, thread.currentThread (). getContextClassLoader ())); } catch (exception finale e) {// ignore}} Retour Résultat; } public static list <string> listClassCanonicalNameofPackage (Final Class <?> Clazz, Extension de chaîne finale) {return ReflectUtils.ListNameOfPackage (Clazz, Extension, True); } public static list <string> listClassNameofPackage (classe finale <?> Clazz, extension finale de chaîne) {return refleftwe.listNameofPackage (Clazz, extension, false); } public static list <string> listNameofPackage (Final Class <?> Clazz, Extension finale de chaîne, final boolean fullpkgname) {return RefleftUtils.ListNameofPackage (Clazz.getName (). Remplace ('. } public static list <string> listNameOfPackage (final String ClazzPKG, extension finale de chaîne, final boolean fullpkgname) {final list <string> result = new ArrayList <string> (); Final StringBuffer pkgBuf = new StringBuffer (ClazzPkg); if (pkgbuf.charat (0)! = '/') pkgbuf.insert (0, '/'); URL final URLPATH = RefleftUtils.class.getResource (pkgbuf.toString ()); if (null == urlPath) Retour Résultat; String checkeDextenion = Extension; if (! extenion.endswith (". class")) checkedextenion = extension + ".class"; if (pkgbuf.toString (). Endswith (". Class"))) pkgbuf.delete (pkgbuf.lastIndexof ("/"), pkgbuf.length ()); pkgbuf.deletecharat (0); Final StringBuffer FileUrl = new StringBuffer (); try {fileUrl.append (urlDEcoder.decode (urlpath.toexternalform (), "utf-8")); } catch (final UnsupportDenCcodingException e1) {fileUrl.append (urlpath.toexternalform ()); } if (fileUrl.toString (). startSwith ("file:")) {fileUrl.delete (0, 5); // delete file: Flag if (fileUrl.indexof (":")! = -1) fileurl.deleTecharat (0); // delete Flag file string basez-bason (FileUrl. ReflectUtils.DolistNameofPackageIndirectory (nouveau fichier (basasedir), nouveau fichier (basaseIr), result, pkgbuf.toString (), checkedextenion, fullpkgname); } else {reflents.dolistNameofPackageInjar (urlPath, urlPath, result, pkgbuf.toString (), checkedextenion, fullpkgname); } Retour Résultat; } / ** * / private static void dolistNameofPackageInjar (final URL BUSTURL, final url urlpath, final list <string> Résultat, final String Clazzpkg, final String Extension, final boolean fullpkgname) {try {// Il ne fonctionne pas avec le fichier de fichiers: nous devons // être dans le cas d'un paquet contenu dans un fichier jar. JarurlConnection finale conn = (jarurlconnection) urlPath.OpenConnection (); jarfile final jfile = conn.getjarfile (); Énumération finale <Jarentry> e = jfile.entries (); Entrée de ziperie; String EntryName; while (e.hasmoreElements ()) {entry = e.NextElement (); entryName = entry.getName (); if (entryName.startswith (ClazzPkg) && entryname.endswith (extenion)) {if (fullpkgname) result.add (entryName.substring (0, entryName.LasTindexof ('.')). Remplace ('/', '.')); else result.add (EntryName.Substring (entryName.LastIndexof ('/') + 1, entryName.LasTindexof ('.'))); }}} catch (final ioException ioEx) {}} private static void dolistNameofPackageIndirectory (Final File-basedirectory, répertoire de fichiers final, liste finale <string> Résultat, final string Clazzpkg, final String Extension, final boolean fullpkgname) {file [] fichiers = répertoire.Listfiles (); if (null == files) files = new File [] {}; String Clazzpath; Final int-basaseLirLlen = basaseDirectory.getAbsoluTepath (). Length () + 1; pour (fichier final de fichier: fichiers) {if (file.isdirectory ()) {reflents.dolistNameofPackageIndirectory (basaseDirectory, file, result, cllazzpkg, extension, fullpkgname); } else {if (! file.getName (). Endswith (Extenion)) continue; if (fullPkGname) {ClazzPath = file.getAbsolutepath (). substring (basaserirlen); CllazzPath = ClazzPath.Substring (0, ClazzPath.length () - 6); result.add (cllazzpath.replace (file.separatorchar, '.')); } else {result.add (file.getName (). substring (0, file.getName (). Length () - 6)); }}}} public static final <T> t initClass (final String implass, final class <t> ttype) {return RefleftUtils.InitClass (implclass, ttype, true); } public static final <T> t initClass (final String implass, final class <t> ttype, final boolean doinit) {try {final object object = class.forname (implass, doinit, thread.currentThread (). getContextClassLoader ()). newInSitance (); return ttype.cast (objet); } Catch (final throwable e) {return null; }}}
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.