Java扫描指定包下的class文件(spring component scan package注解的实现)_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > Java扫描指定包下的class文件(spring component scan package注解的实现)

Java扫描指定包下的class文件(spring component scan package注解的实现)

 2013/8/20 12:36:28  prettyzhou  程序员俱乐部  我要评论(0)
  • 摘要:之前在看spring注解的时候,有看到再配置文件里面定义componentscanpackage就能自动扫描对应包下面的class,然后根据注解生成相应的bean。自己对这个功能很好奇,就搜了下,找到了实现的关键代码,记录下。后续再对这段代码深入学习。Java代码/***从包package中获取所有的Class**@parampack*@return*/publicstaticSet<Class<?>>getClasses(Stringpack)
  • 标签:实现 can 文件 Java Spring 注解 class

? ?之前在看spring注解的时候,有看到再配置文件里面定义component scan package就能自动扫描对应包下面的class

然后根据注解生成相应的bean。自己对这个功能很好奇,就搜了下,找到了实现的关键代码,记录下。后续再对这段代码深入学习。

?

?

Java代码??收藏代码
  1. /**?
  2. ?????*?从包package中获取所有的Class?
  3. ?????*??
  4. ?????*?@param?pack?
  5. ?????*?@return?
  6. ?????*/??
  7. ????public?static?Set<Class<?>>?getClasses(String?pack)?{??
  8. ??
  9. ????????//?第一个class类的集合??
  10. ????????Set<Class<?>>?classes?=?new?LinkedHashSet<Class<?>>();??
  11. ????????//?是否循环迭代??
  12. ????????boolean?recursive?=?true;??
  13. ????????//?获取包的名字?并进行替换??
  14. ????????String?packageName?=?pack;??
  15. ????????String?packageDirName?=?packageName.replace('.',?'/');??
  16. ????????//?定义一个枚举的集合?并进行循环来处理这个目录下的things??
  17. ????????Enumeration<URL>?dirs;??
  18. ????????try?{??
  19. ????????????dirs?=?Thread.currentThread().getContextClassLoader().getResources(??
  20. ????????????????????packageDirName);??
  21. ????????????//?循环迭代下去??
  22. ????????????while?(dirs.hasMoreElements())?{??
  23. ????????????????//?获取下一个元素??
  24. ????????????????URL?url?=?dirs.nextElement();??
  25. ????????????????//?得到协议的名称??
  26. ????????????????String?protocol?=?url.getProtocol();??
  27. ????????????????//?如果是以文件的形式保存在服务器上??
  28. ????????????????if?("file".equals(protocol))?{??
  29. ????????????????????System.err.println("file类型的扫描");??
  30. ????????????????????//?获取包的物理路径??
  31. ????????????????????String?filePath?=?URLDecoder.decode(url.getFile(),?"UTF-8");??
  32. ????????????????????//?以文件的方式扫描整个包下的文件?并添加到集合中??
  33. ????????????????????findAndAddClassesInPackageByFile(packageName,?filePath,??
  34. ????????????????????????????recursive,?classes);??
  35. ????????????????}?else?if?("jar".equals(protocol))?{??
  36. ????????????????????//?如果是jar包文件??
  37. ????????????????????//?定义一个JarFile??
  38. ????????????????????System.err.println("jar类型的扫描");??
  39. ????????????????????JarFile?jar;??
  40. ????????????????????try?{??
  41. ????????????????????????//?获取jar??
  42. ????????????????????????jar?=?((JarURLConnection)?url.openConnection())??
  43. ????????????????????????????????.getJarFile();??
  44. ????????????????????????//?从此jar包?得到一个枚举类??
  45. ????????????????????????Enumeration<JarEntry>?entries?=?jar.entries();??
  46. ????????????????????????//?同样的进行循环迭代??
  47. ????????????????????????while?(entries.hasMoreElements())?{??
  48. ????????????????????????????//?获取jar里的一个实体?可以是目录?和一些jar包里的其他文件?如META-INF等文件??
  49. ????????????????????????????JarEntry?entry?=?entries.nextElement();??
  50. ????????????????????????????String?name?=?entry.getName();??
  51. ????????????????????????????//?如果是以/开头的??
  52. ????????????????????????????if?(name.charAt(0)?==?'/')?{??
  53. ????????????????????????????????//?获取后面的字符串??
  54. ????????????????????????????????name?=?name.substring(1);??
  55. ????????????????????????????}??
  56. ????????????????????????????//?如果前半部分和定义的包名相同??
  57. ????????????????????????????if?(name.startsWith(packageDirName))?{??
  58. ????????????????????????????????int?idx?=?name.lastIndexOf('/');??
  59. ????????????????????????????????//?如果以"/"结尾?是一个包??
  60. ????????????????????????????????if?(idx?!=?-1)?{??
  61. ????????????????????????????????????//?获取包名?把"/"替换成"."??
  62. ????????????????????????????????????packageName?=?name.substring(0,?idx)??
  63. ????????????????????????????????????????????.replace('/',?'.');??
  64. ????????????????????????????????}??
  65. ????????????????????????????????//?如果可以迭代下去?并且是一个包??
  66. ????????????????????????????????if?((idx?!=?-1)?||?recursive)?{??
  67. ????????????????????????????????????//?如果是一个.class文件?而且不是目录??
  68. ????????????????????????????????????if?(name.endsWith(".class")??
  69. ????????????????????????????????????????????&&?!entry.isDirectory())?{??
  70. ????????????????????????????????????????//?去掉后面的".class"?获取真正的类名??
  71. ????????????????????????????????????????String?className?=?name.substring(??
  72. ????????????????????????????????????????????????packageName.length()?+?1,?name??
  73. ????????????????????????????????????????????????????????.length()?-?6);??
  74. ????????????????????????????????????????try?{??
  75. ????????????????????????????????????????????//?添加到classes??
  76. ????????????????????????????????????????????classes.add(Class??
  77. ????????????????????????????????????????????????????.forName(packageName?+?'.'??
  78. ????????????????????????????????????????????????????????????+?className));??
  79. ????????????????????????????????????????}?catch?(ClassNotFoundException?e)?{??
  80. ????????????????????????????????????????????//?log??
  81. ????????????????????????????????????????????//?.error("添加用户自定义视图类错误?找不到此类的.class文件");??
  82. ????????????????????????????????????????????e.printStackTrace();??
  83. ????????????????????????????????????????}??
  84. ????????????????????????????????????}??
  85. ????????????????????????????????}??
  86. ????????????????????????????}??
  87. ????????????????????????}??
  88. ????????????????????}?catch?(IOException?e)?{??
  89. ????????????????????????//?log.error("在扫描用户定义视图时从jar包获取文件出错");??
  90. ????????????????????????e.printStackTrace();??
  91. ????????????????????}??
  92. ????????????????}??
  93. ????????????}??
  94. ????????}?catch?(IOException?e)?{??
  95. ????????????e.printStackTrace();??
  96. ????????}??
  97. ??
  98. ????????return?classes;??
  99. ????}??

?

?

Java代码??收藏代码
  1. /**?
  2. ?????*?以文件的形式来获取包下的所有Class?
  3. ?????*??
  4. ?????*?@param?packageName?
  5. ?????*?@param?packagePath?
  6. ?????*?@param?recursive?
  7. ?????*?@param?classes?
  8. ?????*/??
  9. ????public?static?void?findAndAddClassesInPackageByFile(String?packageName,??
  10. ????????????String?packagePath,?final?boolean?recursive,?Set<Class<?>>?classes)?{??
  11. ????????//?获取此包的目录?建立一个File??
  12. ????????File?dir?=?new?File(packagePath);??
  13. ????????//?如果不存在或者?也不是目录就直接返回??
  14. ????????if?(!dir.exists()?||?!dir.isDirectory())?{??
  15. ????????????//?log.warn("用户定义包名?"?+?packageName?+?"?下没有任何文件");??
  16. ????????????return;??
  17. ????????}??
  18. ????????//?如果存在?就获取包下的所有文件?包括目录??
  19. ????????File[]?dirfiles?=?dir.listFiles(new?FileFilter()?{??
  20. ????????????//?自定义过滤规则?如果可以循环(包含子目录)?或则是以.class结尾的文件(编译好的java类文件)??
  21. ????????????public?boolean?accept(File?file)?{??
  22. ????????????????return?(recursive?&&?file.isDirectory())??
  23. ????????????????????????||?(file.getName().endsWith(".class"));??
  24. ????????????}??
  25. ????????});??
  26. ????????//?循环所有文件??
  27. ????????for?(File?file?:?dirfiles)?{??
  28. ????????????//?如果是目录?则继续扫描??
  29. ????????????if?(file.isDirectory())?{??
  30. ????????????????findAndAddClassesInPackageByFile(packageName?+?"."??
  31. ????????????????????????+?file.getName(),?file.getAbsolutePath(),?recursive,??
  32. ????????????????????????classes);??
  33. ????????????}?else?{??
  34. ????????????????//?如果是java类文件?去掉后面的.class?只留下类名??
  35. ????????????????String?className?=?file.getName().substring(0,??
  36. ????????????????????????file.getName().length()?-?6);??
  37. ????????????????try?{??
  38. ????????????????????//?添加到集合中去??
  39. ????????????????????//classes.add(Class.forName(packageName?+?'.'?+?className));??
  40. ?????????????????????????????????????????//经过回复同学的提醒,这里用forName有一些不好,会触发static方法,没有使用classLoader的load干净??
  41. ????????????????????????????????????????classes.add(Thread.currentThread().getContextClassLoader().loadClass(packageName?+?'.'?+?className));????
  42. ????????????????????????????????}?catch?(ClassNotFoundException?e)?{??
  43. ????????????????????//?log.error("添加用户自定义视图类错误?找不到此类的.class文件");??
  44. ????????????????????e.printStackTrace();??
  45. ????????????????}??
  46. ????????????}??
  47. ????????}??
  48. ????}??

?

?

??????? 自己直接拿过来用了,可以扫描package对应的子package,不过是对当前classLoad下的所有jar进行扫描的。

发表评论
用户名: 匿名