Refleksi Java yang disebutkan kali ini melibatkan banyak kode. Karena refleksi sering digunakan dalam pekerjaan, kami telah membuat banyak abstraksi dan filter ke kode. Meskipun kodenya besar, sederhana dan mudah digunakan, dan filter plug-in juga mudah dimodifikasi.
Berikut ini adalah deskripsi di mana refleksi lebih mudah digunakan dalam pekerjaan. Misalnya, plug-in atau filter, jika ada lebih sedikit subkelas abstrak, mengkonfigurasinya ke XML dan struktur lainnya juga dapat mencapai efek yang sama. Jika Anda ingin lebih fleksibel, Anda dapat menggunakannya langsung setelah menambahkan plug-in atau subkelas kode filter. Mungkin lebih baik untuk mencerminkan, dan semua subclass yang diwariskan diperoleh dengan memindai semua file kelas atau jar. Jika Anda memindai semua file setiap panggilan, itu akan memengaruhi kinerja. Oleh karena itu, cache refleksi ditambahkan ke implementasi untuk menyimpan semua hasil refleksi sebagai kunci untuk semua parameter yang terlibat dalam memperoleh subkelas refleksi. Jika itu adalah kunci yang sama lain kali, Anda tidak akan menyala.
Contoh kode adalah sebagai berikut:
public static void main (string [] args) {// Atur rentang pemindaian, yang dapat menjadi lokasi file kelas, seperti lokasi di bawah bin, atau awal mysql atau akhir mysql, // set "" untuk memindai semua, ini adalah pengambilan waktu, reflectils.creatreshared ("kelas", "class", "class", "class", "class", "class", "class", "class", "class", "class", "class", "class", "class", "class", "class", "class", "class" "," class "," class "," class "," class "," CLASS "," class "," class "," class "," class "," class "," class "," class "; Coba {// Anda dapat mengatur pemindaian penuh setiap kali dalam tahap debugging // beans.setDesigntime (true); Koleksi akhir <string> subtipe = reflectutils.listsubclass (ia.class); // untuk (subtipe string akhir: subtipe) {// apa yang Anda dapatkan di sini adalah system.out.println (subtipe); final IA IMP = reflectutils.initclass (subtipe, ia.class); if (null == IMP) Lanjutkan; // Melalui metode ini, Anda dapat melakukan operasi dengan cara yang terpadu, IMPR.Print (); }} catch (Exception e) {e.printstacktrace (); }}Hasil Eksekusi Kode:
// cache file untuk menghindari penyelamatan setiap kali refleksi dipanggil // Jika Anda menghapus file, itu akan diselamatkan ketika refleksi dipanggil lagi. Secara umum, file akan dihapus ketika ada subkelas dalam kode. Xmlutils.readxml kegagalan: ./ configuration.ref (sistem tidak dapat menemukan file yang ditentukan.) Net.simple.reflect.test.bnet.simple.reflect.test.bnet.simple.reflect.test.bnet.simple.reflect.test.dnet.bnet.simple.reflect.test.dnet.temple.bnet.simple.reflect.test.dnet.dnet.bet
Untuk detailnya, silakan lihat kode sumbernya. Berikut adalah dua kode kelas inti. Alamat kode sumber: https://git.oschina.net/eliyanfei/api_tools
Paket net.simple.reflect; impor java.io.file; impor java.io.ioException; impor java.net.jarurlconnection; impor java.net.url; impor java.net.urldecoder; impor java.util.arraylist; impor java.util; java.util.linkedhashmap; impor java.util.list; impor java.util.map; impor java.util.concurrent.timeunit; impor java.util.jar.jarentry; import java.util.jar.jarfile; impor java.util.zip. net.simple.reflect.filter.ipathurlfilter; impor net.simple.reflect.filter.isubtypefilter; import net.simple.reflect.filter.itypefilter; impor org.w3c.dom.document; impor org.w3c.dom.element; [email protected] * 2 November 2016 jam 3:23:49 PM * */Refleksi Kelas Akhir Publik {Koleksi Final Privat <Url> PathUrls; Koleksi Final Pribadi <Pathurlfilter> Pathurlfilters; Koleksi Final Pribadi <TipePefilter> Typefilters; subtipefilter isubtypefilter pribadi; Public Reflections () {TypeFilters = ArrayList baru <ItypeFilter> (); PathUrlFilters = Daftar ArrayList baru <Pathurlfilter> (); this.pathurls = classpathhelper.getUrlSforcurrentClassPath (); } refleksi publik (Koleksi akhir <Url> PathUrls) {this.pathurls = PathUrls; TypeFilters = Daftar ArrayList baru <ItypeFilter> (); PathUrlFilters = Daftar ArrayList baru <Pathurlfilter> (); } / ** * @param subtipefilter * Subtipefilter untuk mengatur * / public void setSubTypeFilter (final isubtypeFilter subtipeFilter) {this.subtypeFilter = subtipefilter; } / ** * @return Subtipefilter * / public isubtypeFilter getSubtypeFilter () {return subtipeFilter; } Refleksi Publik AddPathUrlFilter (final iPathurlfilter PathUrlfilter) {if (null == pathurlfilter) mengembalikan ini; if (! this.pathurlfilters.contains (pathurlfilter)) this.pathurlfilters.add (pathurlfilter); kembalikan ini; } Public Reflections AddTypeFilter (typefilter final itypeFilter) {if (null == typefilter) kembalikan ini; if (! this.typeFilters.contains (typefilter)) this.typeFilters.add (typeFilter); kembalikan ini; } private static final string histFile = "./configuration.ref"; Histdom dokumen pribadi; Koleksi publik <string> getSubTypesfast (kelas akhir <?> Basetype) {//, string akhir ... Typenames // Filter pertama keluar jalur yang saat ini diizinkan untuk memindai final StringBuilder bufpathsid = New StringBuilder (32); peta akhir <file, url> fileurls = new LinkedHashMap <file, url> (8); untuk (final url pathUrl: pathUrls) {if (! AcceptPathurl (pathUrl)) lanjutkan; File file = null; coba {file = file baru (urldecoder.decode (pathurl.getFile (), "UTF-8")); } catch (pengecualian akhir e) {file = file baru (pathurl.getFile ()); } fileurls.put (file, pathUrl); if (! File.exists ()) // Apakah url file? abaikan lanjut; bufpathsid.append (file.getName ()). append (file.lastmodified ()); } final string domid = md5.getHashString (bufpathsid.toString ()); if (null == histdom) hisdom = w3cutils.readxml (histfile); if (null == histdom) hisdom = w3cutils.newdom ("r"); Elemen 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.setAttribute ("id", domid); } final string baseTypeId = md5.getHashString (Basetype.getName ()); Elemen refele = w3cutils.firstchildeLement (rootele, "e", "id", basetypeID); if (null! = Refele) {daftar akhir <sement> valueeles = w3cutils.childelementList (refele, "f"); Koleksi akhir <string> result = ArrayList baru <string> (valueLes.size ()); untuk (elemen final valueele: valueeles) {result.add (string baru (base64.decodefast (valueele.getAttribute ("id")))); } hasil pengembalian; } ThreadPool akhir <ListSubTypes> pool = ThreadPool baru <NistSubTypes> (); untuk (File Final FileKey: fileurls.keyset ()) {pool.execute (ListSubTypes baru (Basetype, Filey, FileUrls.get (Filekey))); } coba {pool.shutdown (3, timeunit.minutes); } catch (final interruptedException e) {e.printstacktrace (); // untuk debug} koleksi akhir <string> result = arraylist baru <string> (); untuk (final listSubTypes Task: pool.getThreadRunable ()) {result.addall (Task.Result); } refele = w3cutils.addele (rootele, "e"); Refele.setAttribute ("id", BasetypeID); untuk (string final itm: hasil) {w3cutils.addele (refele, "f"). setattribute ("id", base64.encodetoString (itm.getbytes (), false)); } coba {w3cutils.writexmldocument (histfile, histdom); } catch (Exception akhir e) {} hasil pengembalian; } / ** * @see {@link reflectutils#createSharedReflections (string ...)} * @see {@link reflectutils#setSharedReflections (refleksi)} * @see { @reflectutils#listsubclass (class)} * @param basetype * @retype * public * public} @param Basetype * @retype * public * gets (class)} @param BASETYPE * @return * @return * @return * public @parok * @return * public * String ... Typenames) {// ThreadPool akhir <ListSubTypes> pool = ThreadPool baru <NistSubTypes> (); untuk (final url pathUrl: pathUrls) {if (! AcceptPathurl (pathUrl)) lanjutkan; File file = null; coba {file = file baru (urldecoder.decode (pathurl.getFile (), "UTF-8")); } catch (pengecualian akhir e) {file = file baru (pathurl.getFile ()); } pool.execute (ListSubTypes baru (Basetype, File, PathUrl, Typename)); } coba {pool.shutdown (3, timeunit.minutes); } catch (final interruptedException e) {e.printstacktrace (); // untuk debug} koleksi akhir <string> result = arraylist baru <string> (); untuk (final listSubTypes Task: pool.getThreadRunable ()) {result.addall (Task.Result); } hasil pengembalian; } class listSubTypes mengimplementasikan runnable {file final file; Kelas Akhir <?> Basetype; Pathurl URL terakhir; string terakhir [] Jenis Ketik; Public ListSubTypes (kelas akhir <?> Basetype, file file final, PathUrl URL akhir, string akhir ... Typenames) {this.basetype = Basetype; this.file = file; this.pathurl = pathUrl; this.typeNames = Jenis Ketik; } Collection <string> result = ArrayList baru <string> (4); @Override public void run () {if (file.isDirectory ()) {listSubTypesFromDirectory (file, baseType, pathUrl, file, hasil, typenames); } lain ListSubTypesFromJar (Basetype, PathUrl, Hasil, Jenis Ketik); }} / ** * @param Basetype * @param pathUrl * @param hasil * / public void listSubTypesFromDirectory (File Final BasedIrectory, kelas akhir <?> Basetype, URL PathUrl, Direktori File Akhir, Koleksi Akhir <String> Hasil, String Final ... Typename) {File [] [] File = Roreory, Koleksi Final <string> Hasil, string final ... TYPENAME) {file [] [] [] file. if (null == file) file = file baru [] {}; String Clazzpath; final int hasedirlen = bedaredIrectory.getAbsolutePath (). length () + 1; untuk (file file akhir: file) {if (file.isDirectory ()) {listSubTypesFromDirectory (berbasis berdasarkan, baseType, pathUrl, file, hasil, typenames); } else {clazzpath = file.getAbsolutePath (). Substring (berbasis bahasa); clazzpath = clazzpath.replace ('//', '/'); DotypesFilter (Basetype, PathUrl, Hasil, Clazzpath, Jenis Ketik); }}} / ** * @param basetype * @param pathurl * @param hasil * / public void listSubTypesFromJar (kelas akhir <?> Basetype, URL PathUrl, koleksi akhir <string> Hasil, kita harus / cypename) {cobalah {// Ini tidak berfungsi dengan file file: We Wust / Jarfile Jarfile = null; coba {if ("file" .equals (pathurl.getProtocol ())) pathUrl = URL baru ("jar:" + pathurl.toExternalform () + "!/"); jarfile = ((JarurlConnection) pathurl.openconnection ()). getjarfile (); } catch (pengecualian akhir e) {string final filePath = pathurl.getFile (); // jika pada platform Win if (filePath.indexof (':')! = -1) {if (pathurl.getFile (). charaat (0) == '/') Jarfile = Jarfile baru (FilePath.substring (1)); } if (null == Jarfile) Jarfile = New Jarfile (FilePath); } enumeration final <narentry> e = jarfile.entries (); Entri zipentry; while (e.hasmoreElements ()) {entry = e.nextelement (); DotypesFilter (Basetype, PathUrl, Hasil, Entry.getName (), Jenis Ketik); }} catch (ioException final ioex) {}} private void dotypesFilter (kelas akhir <?> Basetype, final URL PathUrl, koleksi akhir <string> hasil, string akhir Clazzpath, string akhir ... Jenis) {if (! clazzpath.endswith (". class") kembali; final int lastDotIdx = clazzpath.LastIndexOf ('.'); if (-1 == lastDotIdx) kembali; string final typedef = clazzpath.substring (0, lastDotidx) .replace ('/', '.'); if (null! = typenames && typeNames.length> 0) {final int lastDot = typedef.LastIndexof ('.'); if (lastDot == -1) kembali; string terakhir typename = typedef.substring (lastDot + 1); boolean withliked = false; untuk (string final tmptypeName: typenames) {if (! typename.contains (tmPtypeName)) lanjutkan; tanpa disukai = true; merusak; } if (withliked == false) return; } if (this.typeFilters.isempty ()) {if (null == this.subtypeFilter || this.subtypeFilter.accept (baseType, pathUrl, clazzpath)) result.add (typedef); } else {for (final itypeFilter typeFilter: this.typeFilters) {if (! typeFilter.accept (clazzpath)) lanjutkan; if (null == this.subtypeFilter || this.subtypeFilter.accept (baseType, pathUrl, clazzpath)) result.add (typedef); }}} / ** * @param pathurl * @return * / private boolean accepathurl (final url pathUrl) {if (this.pathurlfilters.isempty ()) return true; untuk (final ipathurlfilter pathurlfilter: this.pathurlfilters) {if (pathurlfilter.accept (pathurl)) return true; } return false; }}
Paket net.simple.reflect; impor java.beans.beans; impor java.io.file; impor java.io.ioexception; impor java.io.unsupportedencodingException; impor java.net.jarurlconnection; impor java.net.url; impor java.net Java.net. java.util.arraylist; impor java.util.collection; impor java.util.collections; impor java.util.enumeration; import java.util.list; impor java.util.jar.jarentry; impor java.util.jar.jare; impor java. net.simple.reflect.filter.pathurlfilter; impor net.simple.reflect.filter.samplesubinstancefilter; import net.simple.reflect.filter.typefilter;/** * * @Author Li Yanfeei * @emailan eLIYAN; */Public Final Class ReflectUtils {public static final string var_start_flag = "$ {"; string final statis publik var_end_flag = "}"; Refleksi Statis Privat SHAREDREFLEKSI; koleksi final statis <string> emp_coll = collections.emptylist (); public static final void createSharedReflections (string akhir ... filterexts) {final reflections refs = refleksi baru (); refs.addpathurlfilter (pathurlfilter baru (filterexts)); // refs.addtypeFilter (typefilter.default); refs.setsubtypeFilter (sampllesubinstancefilter.default); Reflectutils.SetSharedReflections (Refs); } /*** Metode ini digunakan untuk mengikat alat sirkulasi tipe bersama yang umum. * @param shareDreflection */ public static final setsharedReflections (final reflections sharedreflection) {clevertutils.sharedreflection = sharedreflection; } /*** Sebelum memanggil metode ini, Anda harus terlebih dahulu mengatur alat keliling tipe bersama. Referensi: {@link #setSharedReflection (refleksi)}, * Metode ini terutama membuatnya lebih nyaman untuk mengimplementasikan kelas yang diberikan, */ koleksi akhir statis public <string> ListSubClass (kelas akhir <?> Basetype, string final ... jim) {// if (null == shareDreflecties) return return; // Karena implementasi subclass baru dapat ditambahkan dalam tahap panggilan, perlu diselesaikan setiap kali. Hanya ketika produk diterbitkan, metode menyimpan catatan digunakan untuk meningkatkan kecepatan startup. return beans.isdesigntime ()? shareDreflection.getSubTypes (Basetype, tipename): sharedreflection.getSubTypesfast (baseType); } Daftar statis publik <class <? >> ListClassOfPackage (kelas akhir <?> CType, ekstensi string akhir) {Daftar akhir <class <? >> RAZIN = ARRAYLIST baru <class <? >> (); Daftar Akhir <String> cPath = Reflectutils.ListClassCanonicalNameOfPackage (CTYPE, Extension); untuk (jalur string final: cpath) {coba {result.add (class.forname (path, false, thread.currentThread (). getContextClassLoader ())); } catch (pengecualian akhir e) {// abaikan}} hasil pengembalian; } Daftar Statis Public <string> ListClassCanonicalNameOfPackage (kelas akhir <?> CLAZZ, Ekstensi String Akhir) {return Reflectutils.ListNameOfPackage (Clazz, Extension, True); } Daftar Statis Public <string> ListClassNameOfPackage (Kelas Akhir <?> CLAZZ, Ekstensi String Akhir) {return reflectutils.listnameofpackage (clazz, extension, false); } Daftar statis publik <string> listNameOfPackage (kelas akhir <?> Clazz, ekstensi string final, final fullpkgname) {return clightutils.listnameofpackage (clazz.getName (). REPLACE ('. } Daftar Statis Public <String> ListNameOfPackage (string final Clazzpkg, ekstensi string akhir, final fullpkGname) {daftar akhir <string> hasil = arraylist baru <string> (); final stringBuffer pkgbuf = stringBuffer baru (clazzpkg); if (pkgbuf.charat (0)! = '/') pkgbuf.insert (0, '/'); URL URL Final = reflectutils.class.getResource (pkgbuf.tostring ()); if (null == urlpath) hasil pengembalian; String checkEdextenion = ekstensi; 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 (); coba {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); // hapus file: flag if (fileurl.indexof (":")! = -1) (classies) (0) (0); // hapus bendera string final = umbiurl. Reflectutils.dolistnameofpackageIndirectory (file baru (berbasis), file baru (berbasis), hasil, pkgbuf.tostring (), checkedextenion, fullpkGname); } else {reflectutils.dolistnameofpackageinjar (urlpath, urlpath, hasil, pkgbuf.tostring (), checkedextenion, fullpkgname); } hasil pengembalian; } / *** / private static void dolistnameofpackageinjar (final url baseUrl, final url urlpath, daftar akhir <string> hasil, string clazzpkg, ekstensi string final, final fullpkname) {coba {// tidak berfungsi dengan file. JarurlConnection final conn = (JarurlConnection) urlpath.openconnection (); final Jarfile jfile = conn.getjarfile (); enumeration akhir <sarnentry> e = jfile.entries (); Entri 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 ('.')). Ganti ('/', '. else result.add (entryname.substring (entryname.LastIndexof ('/') + 1, entryname.LastIndexof ('.'))); }}} catch (ioException final ioex) {}} private static void dolistNameOfPackageIndirectory (File Final BasedIrectory, Direktori File Akhir, Daftar Akhir <String> Hasil, String Final Clazzpkg, String Extension, Final Boolean FullPkName) {File [] [] [] File = Directory. if (null == file) file = file baru [] {}; String Clazzpath; final int hasedirlen = bedaredIrectory.getAbsolutePath (). length () + 1; untuk (file file final: file) {if (file.isdirectory ()) {reflectutils.dolistnameofpackageIndirectory (berbasis berdasarkan file, hasil, clazzpkg, ekstensi, fullpkGname); } else {if (! file.getName (). endswith (extenion)) lanjutkan; if (fullpkgname) {clazzpath = file.getAbsolutePath (). Substring (berbasisirlen); clazzpath = clazzpath.substring (0, clazzpath.length () - 6); result.add (clazzpath.replace (file.separatorchar, '.')); } else {result.add (file.getName (). substring (0, file.getName (). Length () - 6)); }}}} public static final <T> t initclass (final string implASS, kelas akhir <t> ttype) {return cliftutils.initclass (implass, ttype, true); } public static final <T> t initclass (final string impllass, final class <t> ttype, final boolean doinit) {coba {objek objek akhir = class.forname (implass, doinit, thread.currentThread (). getContextClassLoader ()). NewInstance (); return ttype.cast (objek); } catch (final throwable e) {return null; }}} Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.