A reflexão Java mencionada desta vez envolve muito código. Como a reflexão é frequentemente usada no trabalho, fizemos muitas abstrações e filtros no código. Embora o código seja grande, é simples e fácil de usar e os plug-ins de filtro também são fáceis de modificar.
A seguir, uma descrição de onde a reflexão é mais fácil de usar no trabalho. Por exemplo, plug-ins ou filtros, se houver menos subclasses abstratas, configurá-los para XML e outras estruturas também podem obter o mesmo efeito. Se você deseja ser mais flexível, pode usá-lo diretamente após adicionar subclasses de plug-ins ou filtro. Pode ser melhor refletir e todas as subclasses herdadas são obtidas com a digitalização de todos os arquivos de classe ou jar. Se você digitalizar todos os arquivos todas as chamadas, isso afetará o desempenho. Portanto, um cache de reflexão é adicionado à implementação para armazenar em cache todos os resultados da reflexão como uma chave para todos os parâmetros envolvidos na obtenção da subclasse de reflexão. Se for a mesma chave na próxima vez, você não será necessário.
O exemplo do código é o seguinte:
public static void main (string [] args) {// Defina o intervalo de varredura, que pode ser a localização do arquivo de classe, como o local sob a lixeira, ou o início do MySQL ou o final de mysql, // definir "" para escanear tudo, isso é demorado, refletir.CreatSaharseflections ("Class"; tente {// você pode definir verificações completas todas as vezes no estágio de depuração // beans.setDesignTime (true); Coleção Final <String> subtypes = refletiTils.listsubclass (iA.class); // para (Subtype final da String: subtipo) {// O que você obtém aqui são System.out.println (subtipo); Final IA Impl = RefletUtils.initclass (subtipo, Ia.class); se (null == impl) continuar; // Através deste método, você pode executar operações de maneira unificada, implic.print (); }} catch (Exceção e) {e.printStackTrace (); }}Resultado da execução do código:
// cache o arquivo para evitar o resgate sempre que reflexo é chamado // Se você excluir o arquivo, ele será rescindido quando o reflexo for chamado novamente. Geralmente, o arquivo será excluído quando houver subclasses no código. Xmlutils.readxml Falha: ./ Configuration.ref (o sistema não pode encontrar o arquivo especificado.) Net.simple.reflect.test.bnet.simple.reflect.test.bnet.simple.reflect.test.bnet.simpLy.reflect.Test.DNELT.SIMPLE.TELT.TEST.BNET.SIMPLO.
Para detalhes, consulte o código -fonte. Aqui estão dois códigos de classes principais. Endereço do código -fonte: https://git.oschina.net/eliyanfei/api_tools
pacote net.simple.REFLECT; importar java.io.file; importar java.io.ioException; importar java.net.jarurlConnection; importar java.net.url; import java.net.urldecoder; import java.util.arraylist; import.enTa.util.Cumil.Collection; importação; java.util.linkedhashmap; importar java.util.list; importar java.util.map; importar java.util.concurrent.timeunit; importar java.util.jar.jarentry; import java.util.Jar.Jarfile; net.simple.reflect.filter.ipathurlfilter; importar net.simple.reflelect.filter.isubtypefilter; importar net.simple.reflect.filter.itypefilter; importação org.w3c.dom.document; import org.w3cdom.emement; [email protected] * 2 de novembro de 2016 às 15:23:49 * */Public Final Class Reflections {Private Final Collection <url> paturls; Coleção final privada <Patathurlfilter> paturlfilters; Coleção final privada <Typefilter> Typefilters; Subtipo privado privado do ISUBTYPEFILTER; public reflexções () {typefilters = new ArrayList <TyPefilter> (); Pathurlfilters = new ArrayList <pathurlfilter> (); this.Pathurls = ClassPathHelper.GeturlsForCurrentClassPath (); } Reflexões públicas (coleção final <url> paturls) {this.pathurls = paturls; typefilters = new ArrayList <TyPefilter> (); Pathurlfilters = new ArrayList <pathurlfilter> (); } / ** * @param subtypefilter * O subttypefilter para definir * / public void Setsubtypefilter (final isubtypefilter subtypefilter) {this.subtypefilter = subtypefilter; } / ** * @return the subtypefilter * / public isubtypefilter getsUbtypefilter () {return subtypefilter; } Reflexões públicas AddPathurlFilter (Pathurlfilter final do ipathurlfilter) {if (null == PATHURLFILTER) Retorne isso; if (! this.pathurlfilters.contains (paturlfilter)) this.pathurlfilters.add (paturlfilter); devolver isso; } Reflexões públicas addTypefilter (iTyPefilter final do iTypefilter) {if (null == typefilter) Retorne isso; if (! this.typefilters.contains (typefilter)) this.typefilters.add (typefilter); devolver isso; } String final estática privada Histfile = "./configuration.ref"; Histdom de documentos privados; Coleção pública <String> getSubtypeSfast (classe final <?> BASETYPE) {//, String final ... typenames // primeiro filtra o caminho atualmente permitido para digitalizar o StringBuilder final bufathsid = new StringBuilder (32); Mapa final <arquivo, url> fileurls = new LinkedHashmap <arquivo, url> (8); para (URL final PATHURL: PATHURLS) {if (! AcceptPathurl (paturl)) continue; Arquivo de arquivo = null; tente {file = new File (urldecoder.decode (paturl.getfile (), "utf-8")); } catch (exceção final e) {file = new File (paturl.getfile ()); } fileurls.put (arquivo, paturl); if (! file.exists ()) // é o arquivo URL? Ignore continue; bufathsid.append (file.getName ()). Append (file.LastModified ()); } string final Domid = md5.gethashString (bufathsid.toString ()); if (null == Histdom) Hisdom = w3cutils.readxml (Histfile); if (null == Histdom) Hisdom = w3cutils.newdom ("r"); Elemento rootele = histDom.getDocumentElement (); if (null == rootele) Histdom.appendChild (rootele = histDom.createElement ("r")); if (! domid.equals (rootele.getAttribute ("id"))) {rootele.getParentNode (). removeChild (rootele); Histdom.AppendChild (Rootele = Histdom.CreateElement ("R")); rootele.setAtAttribute ("id", domid); } string final BasetypeID = md5.gethashString (basetype.getName ()); Elemento refele = w3cutils.firstChildElement (rootele, "e", "id", basetypeID); if (null! = refele) {Final List <lement> valueEles = w3cutils.childElementlist (refele, "f"); Coleção final <String> resultado = new ArrayList <String> (valueeles.size ()); para (elemento final ValueEle: valueEles) {resultado.add (new String (base64.DecodeFast (valueEle.getAttribute ("id"))))); } resultado de retorno; } Final ThreadPool <listsubtypes> pool = new Threadpool <listsubtypes> (); para (FINAL FILEKEY FILEKEY: FILEURLS.KEYSET ()) {POOL.EXECUTE (new ListSubtypes (Basetype, FileKey, Fileurls.get (FileKey))); } tente {pool.shutdown (3, timeUnit.minutes); } catch (final interruptEdException e) {e.printStackTrace (); // para Debug} Coleção Final <string> resultado = new ArrayList <String> (); para (Final ListSubtypes Tarefa: Pool.getThreadRunables ()) {Result.addall (Task.Result); } refele = w3cutils.addele (rootele, "e"); refele.setAttribute ("ID", BASETYPEID); para (string final ITM: resultado) {w3cutils.addele (refele, "f"). setAttribute ("id", base64.EncodeToString (itm.getBytes (), false)); } tente {w3cutils.writexmldocument (histfile, histdom); } catch (Exceção final e) {} Retornar resultado; } / ** * @see {@link refleteTils#CreateSharedReflections (String ...)} * @see {@link RefletUtils#setSharedReflections (reflexões)} * @see {@link refleteTUtils#listsubclass (classe)} * @paramyType * return * * typenames) {// final Threadpool <listsubtypes> pool = new Threadpool <listsubtypes> (); para (URL final PATHURL: PATHURLS) {if (! AcceptPathurl (paturl)) continue; Arquivo de arquivo = null; tente {file = new File (urldecoder.decode (paturl.getfile (), "utf-8")); } catch (exceção final e) {file = new File (paturl.getfile ()); } pool.execute (new listsubtypes (basetype, arquivo, paturl, nomes de tipas)); } tente {pool.shutdown (3, timeUnit.minutes); } catch (final interruptEdException e) {e.printStackTrace (); // para Debug} Coleção Final <string> resultado = new ArrayList <String> (); para (Final ListSubtypes Tarefa: Pool.getThreadRunables ()) {Result.addall (Task.Result); } resultado de retorno; } classe listsubtypes implementa Runnable {Final File File; Classe final <?> BaseType; URL final Pathurl; string final [] nomes de tipos; public listsubtypes (classe final <?> BASETYPE, arquivo final de arquivo, URL final PATHURL, String final ... typenames) {this.BaseType = Basetype; this.File = arquivo; this.Pathurl = paturl; this.typeNames = typenames; } Coleção <string> resultado = new ArrayList <String> (4); @Override public void run () {if (file.isdirectory ()) {listsubtypesFromDirectory (arquivo, baseType, paturl, arquivo, resultado, nomes de tipas); } else listsubtypesFromjar (BaseType, PATHURL, Result, Typenames); }} / ** * @param basEType * @param paturl * @param resultado * / public void listsubtypesFromDirectory (stractory final baseado em arquivos, classe final <?> basEType, URL final Pathurl, diretório de arquivos final, coleta final <string> resultado, string final ... typenames) {files [] if (null == arquivos) arquivos = novo arquivo [] {}; String clazzpath; Final int baseado em base = baseado em base.getabsolutepath (). comprimento () + 1; para (arquivo final Arquivo: Arquivos) {if (file.isdirectory ()) {listsubtypesFromDirectory (baseado em base, bashetype, paturl, arquivo, resultado, nomes de tipas); } else {clazzpath = file.getabsolutepath (). substring (baseado em base); clazzpath = clazzpath.replace ('//', '/'); DotyPesFilter (BaseType, Pathurl, Result, ClazzPath, Typenames); }}} / ** * @param basEType * @param paturl * @param resultado * / public void listsubtypesfromjar (classe final <?> BasEType, url paturl, coleta final <string> Resultado, string final ... typeNames) {Try {// O não funciona com o sistema de arquivos: Jarfile jarfile = nulo; tente {if ("file" .equals (paturl.getProtocol ())) paturl = new url ("jar:" + paturl.toexternalform () + "!/"); jarfile = ((jarurlConnection) paturl.openconnection ()). getjarfile (); } catch (exceção final e) {final string filepath = paturl.getfile (); // se estiver na plataforma win if (filepath.indexof (':')! = -1) {if (paturl.getfile (). charat (0) == '/') jarfile = new jarfile (filepath.substring (1)); } if (null == jarfile) jarfile = new jarfile (filepath); } enumeração final <arentry> e = jarfile.entries (); Entrada de zipentry; while (e.hasMoreElements ()) {Entry = e.NextElement (); DotyPesFilter (BaseType, PATHURL, Result, Entry.getName (), Typenames); }} Catch (ioexception final IoEx) {}} private void dotypesfilter (classe final <?> BasEType, URL final PATHURL, Coleção final <String> Resultado, String final ClazzPath, String final ... Typenames) {if (! Clazzpath.endswith (". Classe"))) Return; final int lastDotIdx = clazzpath.LastIndexOf ('.'); if (-1 == lastDotIdX) retornar; Final String typeDef = clazzpath.substring (0, lastDotIdx) .replace ('/', '.'); if (null! = typenames && typenames.length> 0) {final int lastDot = typedef.lastIndexof ('.'); if (lastDot == -1) retornar; string final typename = typedef.substring (lastDot + 1); booleano sem like = false; para (string final tmpTypeName: typenames) {if (! typename.contains (tmpTypeName)) continue; WithLiked = true; quebrar; } if (withliked == false) retornar; } if (this.typefilters.isEmpty ()) {if (null == this.subtypefilter || this.subtypefilter.accept (basetype, paturl, clazzpath)) result.add (typedef); } else {for (final iTyPefilter typefilter: this.typefilters) {if (! typefilter.accept (clazzpath)) continue; if (null == this.subtypefilter || this.subtypefilter.accept (basetype, paturl, clazzpath)) result.add (typedef); }}} / ** * @param paturl * @return * / private boolean aceithurl (URL final paturl) {if (this.pathurlfilters.isEmpty ()) retorna true; para (Pathurlfilter final do ipathurlfilter: this.pathurlfilters) {if (paturlfilter.accept (paturl)) retorna true; } retornar false; }}
pacote net.simple.reflelect; importar java.beans.beans; importar java.io.file; importar java.io.ioException; importar java.io.unsupportEnCodingException; import java.net.jarurlConnection; importar java.net.uran; 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 net.simple.reflect.filter.PathURLFilter;import net.simple.reflelect.filter.sampleSubInstanceFilter; importar net.simple.reflect.filter.typefilter;/** * * @author li yanfei * @emails [email protected] * novembro 2, 2016 a 3:24:02 Pm */public Finalil Finalilil (2016. 2016 a 3:24: "$ {"; public static final string var_end_flag = "}"; Reflexões estáticas privadas compartilham eflexões; Coleção final estática <String> EMP_COLL = Coleções.Emptylist (); public static final void CreateSharedReflections (String final ... filtroxts) {Final Reflections Refs = new Reflections (); refs.addPathurlfilter (new Pathurlfilter (filterExts)); // refs.addtypefilter (typefilter.default); refs.SetSubtypefilter (SampleSubInstanceFilter.Default); RefletiTils.SetsharedReflections (Refs); } /*** Este método é usado para ligar uma ferramenta de circulação de tipo compartilhado comum. * @param sharedreflections */ public static final void setSharedReflections (reflexões finais compartilhadas) {refletUtils.sharedReflections = sharedReflections; } /*** Antes de chamar esse método, você deve primeiro definir a ferramenta circunferencial do tipo compartilhado. Referência: {@link #SetSharedReflections (reflexões)}, * esse método torna principalmente mais conveniente implementar a classe especificada, */ public static final Collection <String> listSubclass (classe final <?> BasEtype, string final ... nomes) {// if (null == sharedreflection) retornar em_coll; // Como novas implementações de subclasse podem ser adicionadas no estágio de chamada, é necessário rescanar cada vez. Somente quando o produto é publicado, o método de salvar registros é usado para melhorar a velocidade de inicialização. return beans.isdesigntime ()? sharedReflections.getSubtypes (BaseType, typenames): sharedreflections.getsubtypesfast (basetype); } Lista estática pública <classe <? >> listclassofpackage (classe final <?> ctype, extensão final da string) {Final List <class <? >> resultado = new ArrayList <classe <? >> (); Lista final <String> cpath = refletiTils.listclassCanonicalNameOfPackage (ctype, extensão); para (Final String Path: CPath) {try {result.add (class.ForName (Path, False, Thread.CurrentThread (). GetContextClassLoader ()); } catch (Exceção final e) {// ignore}} Retornar resultado; } Lista estática pública <String> listclassCanonicalNameOfPackage (classe final <?> clazz, extensão final da string) {return refletetils.listnameofpackage (clazz, extensão, true); } Lista estática pública <String> listclassNameofPackage (classe final <?> clazz, extensão final da string) {return refletetils.listnameofpackage (clazz, extensão, false); } Lista estática pública <String> listNameOfPackage (classe final <?> clazz, extensão final da string, final boolean fullpkgname) {return refletetils.listnameofpackage (clazz.getname (). reply ('. } Lista estática pública <String> ListNameOfPackage (String final Clazzpkg, Extensão final da String, FullPkgname final finalean) {Final List <tring> resultado = new ArrayList <String> (); final StringBuffer pkgbuf = new StringBuffer (clazzpkg); if (pkgbuf.charat (0)! = '/') pkgbuf.insert (0, '/'); URL FINAL URLPath = refletUtils.class.getResource (pkgbuf.toString ()); if (null == urlpath) Retorno Resultado; String checkedextenion = extensão; if (! Extenion.endSwith (". Classe")) checkedextenion = extension + ".class"; if (pkgbuf.toString (). endswith (". classe"))) pkgbuf.delete (pkgbuf.lastindexof ("/"), pkgbuf.length ()); pkgbuf.deleteCharat (0); final StringBuffer fileurl = new StringBuffer (); tente {fileurl.append (urldecoder.decode (urlpath.toexternalform (), "utf-8")); } Catch (Final UnsupportEdEncodingException e1) {Fileurl.append (urlpath.toexternalform ()); } if (fileurl.tostring (). startSwith ("file:")) {fileurl.delete (0, 5); // Excluir arquivo: sinalizador if (fileurl.indexOf (":")! = -1) fileurl.deleTecharat (0); // Excluir strings finals baseado = fileurl.s. 8); RefleteTUtils.dolistNameofPackageIndirectory (novo arquivo (baseado), novo arquivo (baseado), resultado, pkgbuf.toString (), checkedextenion, fullpkgname); } else {refletUtils.dolistNameofpackageInjar (urlpath, urlpath, resultado, pkgbuf.toString (), checkedextenion, fullpkgname); } resultado de retorno; } / *** / private estático void dolistNameofpackageInjar (URL final BaseUrl, URL Final URLPath, Lista final <String> Resultado, String final Clazzpkg, Extensão final da String, Final Fullpkgname final) {Try {// não trabalha com o sistema de arquivos: deve // estar em FullPer. Final JarurlConnection Conn = (JarurlConnection) urlpath.openconnection (); final jarfile jfile = conn.getjarfile (); enumeração final <arentry> e = jfile.entries (); Entrada de zipentry; 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 ('.').). else Result.add (EntryName.SubString (EntryName.LastIndexof ('/') + 1, EntryName.LastIndexOf ('.'))); }}} catch (ioexception final ioex) {}} private estático void dolistNameofPackageIndirectory (Final Arquivo baseado no diretório de arquivos Final, Lista final <string> Resultado, String final Clazzpkg, Extensão da String Final, Final Boolean Fullgname) {File [] Filzes = FilzesListiles.Listiles, if (null == arquivos) arquivos = novo arquivo [] {}; String clazzpath; Final int baseado em base = baseado em base.getabsolutepath (). comprimento () + 1; para (arquivo final Arquivo: arquivos) {if (file.isdirectory ()) {refleteTULS.DOLISTNAMEOFPACKAGEIDIDERCORTORIA (BASEDIRECTORY, FILE, resultado, clazzpkg, extensão, fullpkgname); } else {if (! file.getName (). ENDSWITH (EXTENION)) continue; if (fullpkgname) {clazzpath = file.getabsolutepath (). substring (baseado em base); clazzpath = clazzpath.substring (0, clazzpath.length () - 6); resultado.add (clazzpath.preplace (file.separatorchar, '.')); } else {result.add (file.getName (). substring (0, file.getName (). length () - 6)); }}}} public static final <t> t initclass (string final ImplClass, classe final <t> ttype) {return refletUtils.initclass (ImplClass, ttype, true); } public static final <t> t initclass (string final ImplClass, classe final <t> ttype, final boolean doinit) {try {final objeto objeto = class.ForName (ImplClass, doinit, thread.currentThread (). getContextClassloader (). retornar ttype.cast (objeto); } catch (lança e final) {return null; }}}
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.