When we use SPRINGMVC, we know that SPRINGMVC can scan all the classes under the specified package, in the usual development, we also have such a scene, so today write a scan package of the tool class, the code is as follows:
PackageCom.gujin.utils;ImportJava.io.File;ImportJava.io.FileFilter;ImportJava.io.IOException;ImportJava.net.JarURLConnection;ImportJava.net.URL;ImportJava.net.URLDecoder;ImportJava.util.ArrayList;ImportJava.util.Enumeration;ImportJava.util.List;ImportJava.util.jar.JarEntry;ImportJava.util.jar.JarFile; Public class hqscanpackage{ /** whether to loop iteration **/ Booleanrecursive =true;/** Package Name Collection **/ PrivateList<string> Packagenames =NewArraylist<string> ();/** Filter **/ PrivateHqscanpackagefilter filter =NULL;/** Listener **/ PrivateHqscanpackagelistener listener =NULL;/** * Whether to loop iteration * * @return */ Public Boolean isrecursive() {returnRecursive }/** * Sets whether to loop iterations * * @param Recursive */ Public void setrecursive(BooleanRecursive) { This. recursive = recursive; }/** * Get filter * * @return * * PublicHqscanpackagefilterGetFilter() {returnFilter }/** * Set Filter * * @param Filter */ Public void SetFilter(Hqscanpackagefilter filter) { This. filter = filter; }/** * Get listener * * @return * * PublicHqscanpackagelistenerGetlistener() {returnListener }/** * Set Listener * * @param Listener */ Public void Setlistener(Hqscanpackagelistener Listener) { This. Listener = Listener; }/** * Add Scan Package * * @param packagename */ Public void Addpackage(String PackageName) {if(PackageName = =NULL|| !packagename.matches ("[\\w]+ (\\.[ \\w]+) * ")) {Throw NewIllegalArgumentException ("Illegal package name."); } This. Packagenames.add (PackageName); }/** * Empty the scan package * / Public void Clearpackage() { This. Packagenames.clear (); }/** * Scan * * * Public void Scan() { for(String packagename:packagenames) {Scan (packagename); } }/** * Accept * * * @param clazz * @return * * Private Boolean Accept(Class<?> clazz) {if( This. filter! =NULL) {return This. filter.accept (Clazz); }return true; }/** * Trigger Scan to legal class * * @param clazz * @return * * Private void Trrigeronscanclass(Class<?> clazz) {if( This. Listener! =NULL) { This. Listener.onscanclass (Clazz); } }/** * Scan to class * * @param clazz * @return * * Private void Onscanclass(Class<?> clazz) {if(Accept (Clazz)) {Trrigeronscanclass (clazz); } }/** * Get all class * * @param packagename * @return * * from the package pack * * Private void Scan(String PackageName) {//Get the name of the package and replace itString packagedirname = Packagename.replace ('. ','/');//Define a set of enumerations to be combined for looping to handle things under this directoryEnumeration<url> dirs =NULL;Try{dirs = Thread.CurrentThread (). Getcontextclassloader (). Getresources (Packagedirname);//loop iteration down while(Dirs.hasmoreelements ()) {//Get Next elementURL url = dirs.nextelement ();//Get the name of the agreementString protocol = Url.getprotocol ();//If it is saved as a file on the server if("File". Equals (protocol)) {//Get the physical path of the packageString FilePath = Urldecoder.decode (Url.getfile (),"UTF-8");//Scan files under the entire package in a file and add them to the collectionFindandaddclassesinpackagebyfile (PackageName, FilePath); }Else if("Jar". Equals (protocol)) {//If it is a jar package file //define a jarfileJarfile jar =NULL;Try{//Get jarJar = ((jarurlconnection) url.openconnection ()). Getjarfile ();//Get an enumeration class from this jar packageenumeration<jarentry> entries = Jar.entries ();//The same loop iteration while(Entries.hasmoreelements ()) {//Get an entity in the jar can be a directory and some other files in the jar package such as meta-inf filesJarentry entry = Entries.nextelement (); String name = Entry.getname ();//If it starts with/ if(Name.charat (0) =='/') {//Get the following stringName = Name.substring (1); }//If the first half and the defined package name are the same if(Name.startswith (Packagedirname)) {intIDX = Name.lastindexof ('/');//If the end of the "/" is a package if(IDX! =-1) {//Get package name replace "/" with "."PackageName = name.substring (0, IDX). Replace ('/','. '); }//If it can be iterated and is a package if(IDX! =-1) || Recursive) {//If it is a. class file and is not a directory if(Name.endswith (". Class") &&!entry.isdirectory ()) {//Remove the ". Class" from the back to get the real class nameString className = name.substring (packagename.length () +1, Name.length ()-6);Try{//Add to Classes //Use Class.forName to trigger class static methodsClass<?> clazz = Thread.CurrentThread (). Getcontextclassloader (). LoadClass ( PackageName +'. '+ ClassName); Onscanclass (Clazz); }Catch(ClassNotFoundException e) {System.err.println ("Loading class error"); } } } } } }Catch(IOException e) {System.err.println ("error getting file from Jar package while scanning user defined view"); E.printstacktrace (); } } } }Catch(IOException e) {System.err.println ("Scan Error"); E.printstacktrace (); } }/** * In the form of a file to get all classes under the package * * @param packagename * @param PackagePath * * Private void Findandaddclassesinpackagebyfile(String PackageName, String PackagePath) {//Get the directory for this package to create a fileFile dir =NewFile (PackagePath);//If it does not exist or is not a directory, return directly if(!dir.exists () | |!dir.isdirectory ()) {System.err.println ("User Defined package name"+ PackageName +"No files under ");return; }//If it exists, get all files under the package including directoryfile[] Dirfiles = Dir.listfiles (NewFileFilter () {//Custom filter rules If you can loop (including subdirectories) or files ending with a. Class (Compiled Java class file) Public Boolean Accept(File file) {return(Recursive && file.isdirectory ()) | | (File.getname (). EndsWith (". Class")); } });//Loop All Files for(File file:dirfiles) {//If it is a directory then continue scanning if(File.isdirectory ()) {Findandaddclassesinpackagebyfile (PackageName +"."+ File.getname (), File.getabsolutepath ()); }Else{//If the Java class file is removed, the following. Class only leaves the class nameString className = File.getname (). SUBSTRING (0, File.getname (). Length ()-6);Try{class<?> clazz = Thread.CurrentThread (). Getcontextclassloader (). LoadClass (Packa Gename +'. '+ ClassName); Onscanclass (Clazz); }Catch(ClassNotFoundException e) {System.err.println ("Adding a user-defined view class error could not find the. class file for this class"); E.printstacktrace (); } } } }/** * Scan packet filter * * @author Jianggujin * */ Public Static interface hqscanpackagefilter { /** * Accept * * * @param clazz * @return * * Public Boolean Accept(Class<?> clazz); }/** * Scan Packet monitoring * * @author Jianggujin * */ Public Static interface hqscanpackagelistener { /** * Scan to legal class execution * * @param clazz */ Public void Onscanclass(Class<?> clazz); } Public Static void Main(string[] args) {Hqscanpackage Scanpackage =NewHqscanpackage (); Scanpackage.addpackage (HQScanPackage.class.getPackage (). GetName ()); Scanpackage.setfilter (NewHqscanpackagefilter () {@Override Public Boolean Accept(Class<?> clazz) {return true; } }); Scanpackage.setlistener (NewHqscanpackagelistener () {@Override Public void Onscanclass(Class<?> clazz) {System.out.println (clazz); } }); Scanpackage.scan (); }}
The following results can be obtained by running:
class com.gujin.utils.HQScanPackage$1
class com.gujin.utils.HQScanPackage$2
class com.gujin.utils.HQScanPackage$3
interface com.gujin.utils.HQScanPackage$HQScanPackageFilter
interface com.gujin.utils.HQScanPackage$HQScanPackageListener
class com.gujin.utils.HQScanPackage
Java Scan Package