이번에 언급 한 Java 반사에는 많은 코드가 포함됩니다. 반사는 종종 작업에 사용되기 때문에 코드에 대한 많은 추상화와 필터를 만들었습니다. 코드는 크지 만 간단하고 사용하기 쉽고 필터 플러그인도 쉽게 수정할 수 있습니다.
다음은 반사가 작업에서 사용하기 쉬운 위치에 대한 설명입니다. 예를 들어, 플러그인 또는 필터는 초록 서브 클래스가 적은 경우 XML 및 기타 구조로 구성하면 동일한 효과를 얻을 수 있습니다. 보다 유연성이 있으려면 플러그인이나 필터 코드 서브 클래스를 추가 한 후 직접 사용할 수 있습니다. 반사하는 것이 더 나을 수 있으며 모든 상속 된 서브 클래스는 모든 클래스 또는 JAR 파일을 스캔하여 얻습니다. 모든 호출마다 모든 파일을 스캔하면 성능에 영향을 미칩니다. 따라서 반사 캐시가 구현에 추가되어 모든 반사 결과를 반사 서브 클래스를 얻는 데 관련된 모든 매개 변수의 키로 모든 반사 결과를 캐시합니다. 다음 번에 같은 키라면 구조하지 않을 것입니다.
코드 예제는 다음과 같습니다.
public static void main (string [] args) {// 스캔 범위를 설정합니다. 스캔 범위를 설정하십시오. 스캔 범위를 설정합니다.이 스캔 범위는 BIN 아래의 위치 또는 MySQL의 시작 또는 MySQL의 시작 또는 MySQL의 끝 "" "" ""모든 것을 스캔하기 위해 "시간이 소요되며,"클래스 ","bin ","mysql "); {// 디버깅 단계에서 매번 전체 스캔을 설정할 수 있습니다. // beans.setDesignTime (true); 최종 컬렉션 <string> subtypes = recintUtils.listSubclass (ia.class); // for (최종 문자열 하위 유형 : 하위 유형) {// 여기에있는 것은 System.out.println (subtype); Final IA impl = reflectUtils.initClass (subtype, ia.class); if (null == emp) 계속; //이 방법을 통해 통합 방식으로 작업을 수행 할 수 있습니다. inmprint (); }} catch (예외 e) {e.printstacktrace (); }}코드 실행 결과 :
// 반사가 호출 될 때마다 구조를 피하기 위해 파일을 캐시합니다. // 파일을 삭제하면 반사가 다시 호출되면 재조정됩니다. 일반적으로 코드에 서브 클래스가있을 때 파일이 삭제됩니다. XMLUTILS.READXML 실패 : ./ configuration.Ref (시스템에서 지정된 파일을 찾을 수 없습니다.
자세한 내용은 소스 코드를 참조하십시오. 다음은 두 가지 핵심 클래스 코드입니다. 소스 코드 주소 : 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.enumeration; java.util.linkedhashmap; import java.util.list; import java.util.map; import java.util.concurrent.timeUnit; import java.util.jar.jarentry; import java.util.jar.jarfile; import java.util.zip.zipentry; 수입; 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* @anfei i* @anfei i* @anfei* @Anfei* @Anfeii* @Anfei* @Anfe. [email protected] * 2016 년 11 월 2 일 오후 3:23:49 * */public final class Reflections {개인 최종 컬렉션 <Url> pathurls; 개인 최종 컬렉션 <IpathurlFilter> PathurlFilters; 개인 최종 컬렉션 <ITYPEFILTER> STROCTFILTERS; 개인 isubtypefilter 하위 유형 피 필터; public Reflections () {saptilters = new ArrayList <ItyPefilter> (); PathurlFilters = New ArrayList <iPathUrlFilter> (); this.pathurls = classPathHelper.getUrlsForCurrentClassPath (); } public Reflections (Final Collection <Url> pathurls) {this.paturls = pathurls; STROFFILTERS = New ArrayList <ItyPefilter> (); PathurlFilters = New ArrayList <iPathUrlFilter> (); } / ** * @param subtypefilter * subtypefilter * / public void setsubtypefilter (final isubtypefilter subtypefilter) {this.subtypefilter = subtypefilter; } / ** * @하위 유형 피 필터 * / public isubtypefilter getsubtypefilter () {return subtypefilter; } public Reflections addPathurlFilter (최종 iPathUrlFilter pathurlFilter) {if (null == pathurlfilter) 이것을 반환합니다. if (! this.paturlfilters.contains (pathurlfilter)) this.pathurlfilters.add (pathurlfilter); 이것을 반환하십시오; } public Reflections addTyPefilter (최종 ITYPEFILTER STRIPILTER) {if (null == stefilter) 이것을 반환합니다. if (! this.typefilters.contains (staplefilter)) this.typefilters.add (stiptilter); 이것을 반환하십시오; } 개인 정적 최종 문자열 histfile = "./configuration.ref"; 개인 문서 histdom; 공개 컬렉션 <string> getSubtypesfast (최종 클래스 <?> Basetype) {//, 최종 문자열 ... TypeNames // 현재 최종 StringBuilder BufPathSID = New StringBuilder (32)를 스캔 할 수있는 경로를 필터링합니다. 최종지도 <file, url> fileUrls = new LinkedHashMap <file, url> (8); for (final url pathurl : pathurls) {if (! accept pathurl (pathurl)) 계속; 파일 파일 = null; try {file = new File (urldecoder.decode (pathurl.getfile (), "utf-8")); } catch (Final Exception e) {file = 새 파일 (pathurl.getFile ()); } fileUrls.put (file, pathurl); if (! file.exists ()) //는 URL 파일입니까? bufpathsid.append (file.getname ()). append (file.lastModified ()); } 최종 문자열 domid = md5.gethashstring (bufpathsid.tostring ()); if (null == histdom) hisdom = w3cutils.readxml (histfile); if (null == histdom) hisdom = w3cutils.newdom ( "r"); 요소 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); } 최종 문자열 baseTypeId = md5.gethashString (baseType.getName ()); 요소 refele = w3cutils.firstChildElement (rootele, "e", "id", baseTypeId); if (null! = refele) {Final List <emetereles = w3cutils.childelementList (refele, "f"); 최종 컬렉션 <String> 결과 = New ArrayList <string> (ValueEles.size ()); for (final element valueele : valueeles) {result.add (new String (base64.decodefast (valueele.getAttribute ( "id"))); } 반환 결과; } final ThreadPool <StubTypes> pool = new ThreadPool <listSubTypes> (); for (final fileKey : fileUrls.Keyset ()) {pool.Execute (새 ListSubTypes (BaseType, fileKey, fileUrls.get (fileKey))); } try {pool.shutdown (3, timeUnit.minutes); } catch (Final InterruptedException e) {e.printstacktrace (); debug for debug} final collection <string> result = new arraylist <string> (); for (final listSubTypes task : pool.getThreadRunables ()) {result.addall (task.result); } refele = w3cutils.addele (rootele, "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, histdom); } catch (최종 예외 e) {} return result; } / ** * @see {@link reflexutils#createSharedReflession (string ...)} * @see {@link reflexutils#setsharedReflection (반사)} * @see {@link reflectUtils#listsubclass (class) * @param basetyth * / public collection <string> base string> typeNames) {// final ThreadPool <listSubTypes> pool = new ThreadPool <listSubTypes> (); for (final url pathurl : pathurls) {if (! accept pathurl (pathurl)) 계속; 파일 파일 = null; try {file = new File (urldecoder.decode (pathurl.getfile (), "utf-8")); } catch (Final Exception e) {file = 새 파일 (pathurl.getFile ()); } pool.Execute (새 ListSubTypes (BaseType, File, Pathurl, TypeNames)); } try {pool.shutdown (3, timeUnit.minutes); } catch (Final InterruptedException e) {e.printstacktrace (); debug for debug} final collection <string> result = new arraylist <string> (); for (final listSubTypes task : pool.getThreadRunables ()) {result.addall (task.result); } 반환 결과; } class listSubTypes는 runnable {최종 파일 파일; 최종 클래스 <?>베이스 타입; 최종 URL Pathurl; 최종 문자열 [] 유형 이름; public listSubTypes (Final Class <?> BaseType, 최종 파일 파일, 최종 URL Pathurl, Final String ... TypeNames) {this.baseType = BaseType; this.file = 파일; this.pathurl = pathurl; this.typenames = typeNames; } collection <string> result = new ArrayList <String> (4); @override public void run () {if (file.isdirectory ()) {listSubTypesFromDirectory (file, baseType, pathurl, file, result, typeNames); } else listSubTeBesfromjar (BaseType, pathurl, result, typeNames); }} / ** * @param basetype * @param pathurl * @param result * / public void listsubtypesfromDirectory (최종 파일 기반 디렉토리, 최종 클래스 <?> 최종 경로, 최종 파일 디렉토리, 최종 수집 <string> 결과, 최종 문자열 ... typeNames) {files = directory.listFiles (); if (null == files) files = 새 파일 [] {}; 문자열 ClazzPath; Final int Basedirlen = basedirectory.getabsolutepath (). length () + 1; for (final file : files) {if (file.isdirectory ()) {listSubTypesfromDirectory (Basedirectory, BaseType, Pathurl, file, result, typeNames); } else {clazzpath = file.getabsolutepath (). 서브 스트링 (기반); ClazzPath = ClazzPath.replace ( '//', '/'); dotypesfilter (Basetype, Pathurl, result, clazzpath, typeNames); }}} / ** * @param baseType * @param pathurl * @param result * / public void listsubtypesfromjar (Final Class <?> url pathurl, final collection <string> 결과, 최종 문자열 ... typenames) {// 파일과 함께 작동하지 않아야합니다. jarfile jarfile = null; try {if ( "file".equals (pathurl.getProtocol ())) pathurl = new URL ( "jar :" + pathurl.toexternalform () + "!/"); jarfile = ((JarurlConnection) pathurl.openConnection ()). getJarfile (); } catch (Final Exception e) {Final String FilePath = pathurl.getFile (); // if in win platform if (filepath.indexof ( ':')! = -1) {if (pathurl.getfile (). charat (0) == '/') jarfile = new Jarfile (filepath.substring (1)); } if (null == jarfile) jarfile = new jarfile (filepath); } 최종 열거 <jarentry> e = jarfile.entries (); zipentry 항목; while (e.hasmoreElements ()) {entry = e.nextElement (); dotypesFilter (BaseType, pathurl, result, entry.getName (), typeNames); }} catch (Final IoException ioex) {}} private void dotypesfilter (Final Class <?> Basetype, 최종 URL Pathurl, Final Collection <String> 결과, 최종 문자열 ClazzPath, 최종 문자열 ... TypEnames) {if (! clazzPath.EndSwith ( ". class")); 최종 int lastDotidx = clazzpath.lastIndexof ( '.'); if (-1 == lastDoTidx) 반환; 최종 문자열 typedef = clazzpath.substring (0, lastDotIdx) .replace ( '/', '.'); if (null! = typenames && typenames.length> 0) {Final int lastDot = typedef.lastIndexof ( '.'); if (lastdot == -1) 반환; 최종 문자열 typename = typedef.substring (lastdot + 1); 부울 withliked = false; for (최종 문자열 tmptypename : typenames) {if (! typename.contains (tmptypename)) 계속; withliked = true; 부서지다; } if (withliked == false) 반환; } if (this.typefilters.isempty ()) {if (null == this.subtypefilter || this.subtypefilter.accept (BaseType, Pathurl, ClazzPath)) result.add (typedef); } else {for (final itypefilter sypilter : this.typefilters) {if (! saptefilter.accept (clazzpath)) 계속; if (null == this.subtypefilter || this.subtypefilter.accept (Basetype, pathurl, clazzpath)) result.add (typedef); }}} / ** * @param pathurl * @return * / private boolean accept pathurl (final url paturl) {if (this.pathurlfilters.isempty ()) true; for (최종 ipathurlfilter pathurlfilter : this.pathurlfilters) {if (pathurlfilter.accept (pathurl)) true; } false를 반환합니다. }}
package net.simple.reflect; import java.beans.beans; import java.io.file; import java.io.ioexception; import java.io.unsupportedencodingException; import java.net.jarurlconnection; import java.net.url; import java.net.urldecer; 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.simplec.simplect.simple.simplect net.simple.reflect.filter.sampleSubinstancefilter; import net.simple.reflect.filter.typefilter;/** * * * @author li yanfei * @email [email protected] * 11 월 2 일 오후 3시 24 분 */public string final class var_flag {public string var_flag var_flag "$ {"; 공개 정적 최종 문자열 var_end_flag = "}"; 개인 정적 반사 공유 반응; 정적 최종 컬렉션 <string> emp_coll = collections.emptylist (); 공개 정적 최종 void CreateSharedReflession (Final String ... Filterexts) {Final Reflections refs = new Reflections (); refs.AddPathurlFilter (New PathurlFilter (FilterExts)); // refs.AdDtyPefilter (saptfilter.default); refs.setsubtypefilter (samplesubinstancefilter.default); ReflectUtils.setsharedReflession (refs); } /***이 방법은 공통 공유 유형 순환 도구를 바인딩하는 데 사용됩니다. * @param sharedReflession */ public static final void setsharedReflession (최종 반사 sharedReflession) {reflectUls.sharedReflession = sharedReflections; } /***이 메소드를 호출하기 전에 먼저 공유 유형 원주 도구를 설정해야합니다. 참조 : {@link #setsharedReflections (반사)}, *이 메소드는 주로 주어진 클래스를 구현하는 것이 더 편리합니다. */ public static final collection <string> listSubclass (final class <?> baseType, 최종 문자열 ... TypeNames) {// if (null == sharedReflests) return Emp_coll; // 새로운 서브 클래스 구현이 통화 단계에 추가 될 수 있으므로 매번 구조해야합니다. 제품이 게시 될 때만 레코드를 저장하는 방법은 시작 속도를 향상시키는 데 사용됩니다. 반환 beans.isdesigntime ()? sharedReflections.getSubTypes (BaseType, typeNames) : sharedReflections.getSubtypesfast (BaseType); } public static list <class <? >> listClassofPackage (Final Class <?> ctype, Final String Extension) {최종 목록 <class <? >> result = new arraylist <class <? >> (); 최종 목록 <string> cpath = reflectUls.listClassCanonicalNameOfPackage (ctype, extension); for (final String path : cpath) {try {result.add (class.forname (path, false, strook.currentThread (). getContextClassLoader ())); } catch (최종 예외 e) {// ingore}} return result; } public static list <string> listClassCanonicalNameOfPackage (Final Class <?> Clazz, Final String Extension) {return reflectUtils.listNameOfPackage (Clazz, Extension, True); } public static list <string> listclassnameofpackage (Final Class <?> Clazz, Final String Extension) {return reflectUtils.listnameofpackage (Clazz, Extension, False); } public static list <String> ListNameOfPackage (Final Class <?> 클라그, 최종 문자열 확장, 최종 부울 FullPKGname) {return reflicEtils.listnameofpackage (clazz.getName (). 교체 ( '.', '/') + ".class", Extension, fullPkgname); } public static list <string> listnameofpackage (최종 문자열 clazzpkg, 최종 문자열 확장, 최종 부울 fullpkgname) {final list <string> result = new arraylist <string> (); 최종 StringBuffer pkgbuf = new StringBuffer (clazzpkg); if (pkgbuf.charat (0)! = '/') pkgbuf.insert (0, '/'); 최종 URL URLPATH = ReflectUtils.class.getResource (pkgbuf.toString ()); if (null == urlpath) 반환 결과; 문자열 checkedextenion = 확장자; if (! extenion.endswith ( ". class")) checkedextenion = extension + ".class"; if (pkgbuf.tostring (). endswith ( ". class"))) pkgbuf.delete (pkgbuf.lastindexof ( "/"), pkgbuf.length ()); pkgbuf.deletecharat (0); 최종 StringBuffer fileUrl = new StringBuffer (); try {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); // 파일 삭제 : flag (fileUrl.indexof ( ":")! = -1) fileUrl.deleteCharat (0); // FILEURL. (0, fileUrl.1)) recelfUtils.dolistNameOfPackageIndirectory (새 파일 (기반), 새 파일 (기반), 결과, pkgbuf.tostring (), checkedextenion, fullpkgname); } else {reflectUtils.dolistNameOfPackAgeInjar (urlpath, urlpath, result, pkgbuf.tostring (), checkedextenion, fullpkgname); } 반환 결과; } / *** / private static void dolistnameofpackageInjar (최종 URL BaseUrl, 최종 URL URL 경로, 최종 목록 <String> 결과, 최종 문자열 ClazzPKG, Final String Extension, Final Boolean FullPKGname) {파일 시스템과 함께 작동하지 않아야합니다. 최종 JarurlConnection Conn = (JarurlConnection) urlpath.openConnection (); 최종 Jarfile Jfile = conn.getJarfile (); 최종 열거 <jarentry> e = jfile.entries (); zipentry 항목; 문자열 입력 이름; while (e.hasmoreElements ()) {entry = e.nextElement (); EntryName = Entry.GetName (); if (EntryName.startSwith (clazzpkg) && entermentname.endswith (extenion)) {if (fullpkgname) result.add (EntryName.SubString (0, entherName.LastIndexOf ( '.')). Replare ( '/', '.')); else result.add (EntryName.SubString (EntryName.LastIndexOf ( '/')) + 1, entermname.lastIndexof ( '.'))); }}} catch (Final IoException ioex) {}} 개인 정적 void dolistnameofpackageIndirectory (최종 파일 기반 디렉토리, 최종 파일 디렉토리, 최종 목록 <String> 결과, 최종 문자열 ClazzPKG, 최종 문자열 확장, 최종 부울 fullpkgname) {파일 = directory.listfiles (); if (null == files) files = 새 파일 [] {}; 문자열 ClazzPath; Final int Basedirlen = basedirectory.getabsolutepath (). length () + 1; for (final file : files) {if (file.isdirectory ()) {reformutils.dolistnameofpackageIndirectory (basedirectory, file, result, clazzpkg, extension, fullpkgname); } else {if (! file.getName (). EndSwith (extenion)) 계속; if (fullpkgname) {clazzpath = file.getabsolutepath (). substring (기반); 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 emprclass, Final Class <T> ttype) {return refultUtils.initClass (emprClass, ttype, true); } public static final <t> t initclass (최종 문자열 emprclass, 최종 클래스 <t> ttype, final boolean doinit) {try {final object = class.forname (emplclass, doinit, stride.currentthread (). getContextClassLoader ()). newInstance (); return ttype.cast (Object); } catch (Final Throwable e) {return null; }}}
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.