The previously described Annotationprocessor can generate a custom class at compile time, but there is a disadvantage, can only add/delete java files will be executed every time, the other day, a person does not know the pit is big
Remember the compile-time processing, lazy processing, and a preprocessing that was introduced before, right?
Preprocessing: Processing before the application starts, such as Setup
Scan class Processing
1. Read all classpath from ClassLoader and System.getproperty ("Java.class.path")
2. Explain each classpath, match Jar/class file with regular
3. Regular extraction class name, converted to class to the upper processing
1 Public classPackagescanner {2 Private Static FinalLogger Logger = Loggerfactory.getlogger (Packagescanner.class);3 4 /**5 * @paramPackagenames6 * Filter the package name, if NULL to scan all classes7 */8 Public Static voidScan (consumer<class<?>> atcion,FinalString ... packagenames) {9Set<string> ClassPath =NewHashset<>();TenSet<string> Filterpackage =NewHashset<>(); One if(Packagenames = =NULL|| Packagenames.length = = 0) { AString Classpathprop = System.getproperty ("Java.class.path"); - if(Classpathprop! =NULL) { -string[] Classpathentries =Classpathprop.split (file.pathseparator); the for(String cpe:classpathentries) { -CPE = TRIMR (CPE, '/')); -Classpath.add (NewFile (CPE). GetAbsolutePath ()); - } + } -ClassLoader cl =Classloader.getsystemclassloader (); +url[] URLs =((URLClassLoader) cl). Geturls (); A for(URL url:urls) { atString path = TRIMR (Url.getpath (), '/'); -Classpath.add (NewFile (path). GetAbsolutePath ()); - } -}Else { - Collections.addall (ClassPath, packagenames); - Collections.addall (Filterpackage, packagenames); in } - to /*** + * Scanning has three kinds of strategies - * 1.jar File the * 2.class File * * 3.classPath Catalogue $ * */Panax Notoginseng - for(String path:classpath) { the Try { + if(Path.endswith (". Jar")) { A Parsejar (Path, filterpackage, atcion); the}Else if(NewFile (path). Isdirectory ()) { +Parsefile (Path,NULL, Filterpackage, atcion); -}Else { $ FinalString packagedirectory = Path.replace ('. ', '/')); $ Finalenumeration<url> URLs =Thread.CurrentThread (). Getcontextclassloader (). Getresources (packagedirectory); - while(Urls.hasmoreelements ()) { - FinalURL url =urls.nextelement (); the if("File". Equals (Url.getprotocol ())) { -Parsefile (Url.getpath (), Url.getpath (). Replace (Packagedirectory, ""), filterpackage,atcion);Wuyi}Else if("Jar". Equals (Url.getprotocol ())) { the Parsejar (Url.getpath (), Filterpackage, atcion); - } Wu } - } About}Catch(Exception Exception) { $ Throw Newruntimeexception (exception); - } - } - } A}
Parsejar,parsefile more long, interested readers can check the source analysis
Some of the class reads in the jar will go wrong because they are not dependent on the complete package
Test:
1 Public classTestscanclass {2 3 @Test4 Public voidTestall () {5Packagescanner.scan ((CLZ) {6 //System.out.println (CLZ);7 });8 }9 Ten @Test One Public voidTestFilter1 () { APackagescanner.scan ((CLZ) { - System.out.println (CLZ); -}, "Com.eyu.onequeue"); the } - - @Test - Public voidTestfilter () { +set<class<?>> values =NewHashset<>(); -Packagescanner.scan ((CLZ) { +Qmodel Modelanno = Reflectutil.getanno (CLZ, Qmodel.class); A if(Modelanno = =NULL) { at return; - } - Values.add (CLZ); -}, "Com.eyu.onequeue"); - for(class<?>clz:values) { - if(Clz.isinterface ()) { in Qrpcfactory.registersendproxy (CLZ); -System.out.println ("Registersendproxy:" +CLZ); to}Else { + Try { - Qrpcfactory.registerreceiveproxy (Clz.newinstance ()); theSystem.out.println ("Registerreceiveproxy:" +CLZ); *}Catch(Exception e) { $ e.printstacktrace ();Panax Notoginseng } - } the } + } A}
[Weave message Frame] [Java Core Technology] Dynamic Agent application 9-Scan class