java工具类-获取包下的所有类

可以获取文件形式的也可以获取jar包形式的
  1. packagecom.ergal.ezweb.utils;
  2. importjava.io.File;
  3. importjava.io.FileFilter;
  4. importjava.io.IOException;
  5. importjava.net.JarURLConnection;
  6. importjava.net.URL;
  7. importjava.net.URLDecoder;
  8. importjava.util.Enumeration;
  9. importjava.util.LinkedHashSet;
  10. importjava.util.Set;
  11. importjava.util.jar.JarEntry;
  12. importjava.util.jar.JarFile;
  13. importorg.apache.commons.logging.Log;
  14. importorg.apache.commons.logging.LogFactory;
  15. /**
  16. *类相关的工具类
  17. *
  18. *@author<ahref="mailto:[email protected]">ohergal</a>
  19. *
  20. */
  21. publicclassClassUtil{
  22. privatestaticfinalLoglog=LogFactory.getLog(ClassUtil.class);
  23. /*
  24. *取得某一类所在包的所有类名不含迭代
  25. */
  26. publicstaticString[]getPackageAllClassName(StringclassLocation,StringpackageName){
  27. //将packageName分解
  28. String[]packagePathSplit=packageName.split("[.]");
  29. StringrealClassLocation=classLocation;
  30. intpackageLength=packagePathSplit.length;
  31. for(inti=0;i<packageLength;i++){
  32. realClassLocation=realClassLocation+File.separator+packagePathSplit[i];
  33. }
  34. FilepackeageDir=newFile(realClassLocation);
  35. if(packeageDir.isDirectory()){
  36. String[]allClassName=packeageDir.list();
  37. returnallClassName;
  38. }
  39. returnnull;
  40. }
  41. /**
  42. *从包package中获取所有的Class
  43. *@parampack
  44. *@return
  45. */
  46. publicstaticSet<Class<?>>getClasses(Packagepack){
  47. //第一个class类的集合
  48. Set<Class<?>>classes=newLinkedHashSet<Class<?>>();
  49. //是否循环迭代
  50. booleanrecursive=true;
  51. //获取包的名字并进行替换
  52. StringpackageName=pack.getName();
  53. StringpackageDirName=packageName.replace('.','/');
  54. //定义一个枚举的集合并进行循环来处理这个目录下的things
  55. Enumeration<URL>dirs;
  56. try{
  57. dirs=Thread.currentThread().getContextClassLoader().getResources(packageDirName);
  58. //循环迭代下去
  59. while(dirs.hasMoreElements()){
  60. //获取下一个元素
  61. URLurl=dirs.nextElement();
  62. //得到协议的名称
  63. Stringprotocol=url.getProtocol();
  64. //如果是以文件的形式保存在服务器上
  65. if("file".equals(protocol)){
  66. //获取包的物理路径
  67. StringfilePath=URLDecoder.decode(url.getFile(),"UTF-8");
  68. //以文件的方式扫描整个包下的文件并添加到集合中
  69. findAndAddClassesInPackageByFile(packageName,filePath,recursive,classes);
  70. }elseif("jar".equals(protocol)){
  71. //如果是jar包文件
  72. //定义一个JarFile
  73. JarFilejar;
  74. try{
  75. //获取jar
  76. jar=((JarURLConnection)url.openConnection()).getJarFile();
  77. //从此jar包得到一个枚举类
  78. Enumeration<JarEntry>entries=jar.entries();
  79. //同样的进行循环迭代
  80. while(entries.hasMoreElements()){
  81. //获取jar里的一个实体可以是目录和一些jar包里的其他文件如META-INF等文件
  82. JarEntryentry=entries.nextElement();
  83. Stringname=entry.getName();
  84. //如果是以/开头的
  85. if(name.charAt(0)=='/'){
  86. //获取后面的字符串
  87. name=name.substring(1);
  88. }
  89. //如果前半部分和定义的包名相同
  90. if(name.startsWith(packageDirName)){
  91. intidx=name.lastIndexOf('/');
  92. //如果以"/"结尾是一个包
  93. if(idx!=-1){
  94. //获取包名把"/"替换成"."
  95. packageName=name.substring(0,idx).replace('/','.');
  96. }
  97. //如果可以迭代下去并且是一个包
  98. if((idx!=-1)||recursive){
  99. //如果是一个.class文件而且不是目录
  100. if(name.endsWith(".class")&&!entry.isDirectory()){
  101. //去掉后面的".class"获取真正的类名
  102. StringclassName=name.substring(packageName.length()+1,name.length()-6);
  103. try{
  104. //添加到classes
  105. classes.add(Class.forName(packageName+'.'+className));
  106. }catch(ClassNotFoundExceptione){
  107. log.error("添加用户自定义视图类错误找不到此类的.class文件");
  108. e.printStackTrace();
  109. }
  110. }
  111. }
  112. }
  113. }
  114. }catch(IOExceptione){
  115. log.error("在扫描用户定义视图时从jar包获取文件出错");
  116. e.printStackTrace();
  117. }
  118. }
  119. }
  120. }catch(IOExceptione){
  121. e.printStackTrace();
  122. }
  123. returnclasses;
  124. }
  125. /**
  126. *以文件的形式来获取包下的所有Class
  127. *@parampackageName
  128. *@parampackagePath
  129. *@paramrecursive
  130. *@paramclasses
  131. */
  132. publicstaticvoidfindAndAddClassesInPackageByFile(StringpackageName,StringpackagePath,finalbooleanrecursive,Set<Class<?>>classes){
  133. //获取此包的目录建立一个File
  134. Filedir=newFile(packagePath);
  135. //如果不存在或者也不是目录就直接返回
  136. if(!dir.exists()||!dir.isDirectory()){
  137. log.warn("用户定义包名"+packageName+"下没有任何文件");
  138. return;
  139. }
  140. //如果存在就获取包下的所有文件包括目录
  141. File[]dirfiles=dir.listFiles(newFileFilter(){
  142. //自定义过滤规则如果可以循环(包含子目录)或则是以.class结尾的文件(编译好的java类文件)
  143. publicbooleanaccept(Filefile){
  144. return(recursive&&file.isDirectory())||(file.getName().endsWith(".class"));
  145. }
  146. });
  147. //循环所有文件
  148. for(Filefile:dirfiles){
  149. //如果是目录则继续扫描
  150. if(file.isDirectory()){
  151. findAndAddClassesInPackageByFile(packageName+"."+file.getName(),
  152. file.getAbsolutePath(),
  153. recursive,
  154. classes);
  155. }
  156. else{
  157. //如果是java类文件去掉后面的.class只留下类名
  158. StringclassName=file.getName().substring(0,file.getName().length()-6);
  159. try{
  160. //添加到集合中去
  161. classes.add(Class.forName(packageName+'.'+className));
  162. }catch(ClassNotFoundExceptione){
  163. log.error("添加用户自定义视图类错误找不到此类的.class文件");
  164. e.printStackTrace();
  165. }
  166. }
  167. }
  168. }
  169. }

你可能感兴趣的:(java)