当前位置: 首页 > >

获取指定包名下所有的类

发布时间:

我们需要开发一个类加*鳎醇釉馗没“碌乃欣啵热缡褂昧四匙⒔獾睦啵蚴迪至四辰涌诘睦啵诨蛘呒坛辛四掣咐嗟乃凶永唷

? ? ? ?下一个ClassUtil工具类作为类加*鳎峁┯肜嘞喙氐姆椒ǎ热缁袢±嗉釉*鳎釉乩啵袢≈付ò碌乃欣唷lassUtil的代码如下:






[java]
view plain
copy
print
?


  1. package?org.smart4j.framework.org.smart4j.framework.util;????
  2. import?org.apache.commons.lang3.StringUtils;??import?org.slf4j.Logger;??
  3. import?org.slf4j.LoggerFactory;????
  4. import?java.io.File;??import?java.io.FileFilter;??
  5. import?java.net.JarURLConnection;??import?java.net.URL;??
  6. import?java.util.Enumeration;??import?java.util.HashSet;??
  7. import?java.util.Set;??import?java.util.jar.JarEntry;??
  8. import?java.util.jar.JarFile;????
  9. /**??*?Created?by?jack?on?2017/5/22.?
  10. ?*?类操作工具类??*/??
  11. public?final?class?ClassUtil?{??????private?static?final?Logger?LOGGER?=?LoggerFactory.getLogger(ClassUtil.class);??
  12. ??????/**?
  13. ?????*?获取类加*??????*?获取加*骼嗟氖迪直冉霞虻ィ恍杌袢〉鼻跋叱痰腃lassLoader?
  14. ?????*/??????public?static?ClassLoader?getClassLoader()?{??
  15. ????????return?Thread.currentThread().getContextClassLoader();??????}??
  16. ??????/**?
  17. ?????*?加载类??????*?加载类需要提供类名与是否初始化的标志,这里提到的初始化指是否执行类的静态代码块;?
  18. ?????*?为了提高加载类的性能,可以将loadClass方法的isInitialized参数设置false??????*/??
  19. ????public?static?Class?loadClass(String?className,?boolean?isInitialized)?{??????????Class?cls?=?null;??
  20. ????????try?{??????????????//进行类加载??
  21. ????????????cls?=?Class.forName(className,?isInitialized,?getClassLoader());??????????}?catch?(ClassNotFoundException?e)?{??
  22. ????????????LOGGER.error("load?class?failure.",?e);??????????????throw?new?RuntimeException(e);??
  23. ????????}??????????return?cls;??
  24. ????}????
  25. ????/**??????*?获取指定包名下所有的类;?
  26. ?????*?获取指定包名下所有的类,需要根据包名并将其转换为文件路径,读取class文件或jar包,获取指定的类名去加载类??????*/??
  27. ????public?static?Set>?getClassSet(String?packageName)?{??????????Set>?classSet?=?new?HashSet>();??
  28. ????????try?{??????????????Enumeration?urls?=?getClassLoader().getResources(packageName.replace(".",?"/"));??
  29. ????????????while?(urls.hasMoreElements())?{??????????????????URL?url?=?urls.nextElement();??
  30. ????????????????if?(url?!=?null)?{??????????????????????String?protocol?=?url.getProtocol();??
  31. ????????????????????if?("file".equals(protocol))?{??????????????????????????String?packagePath?=?url.getPath().replace("%20",?"");??
  32. ????????????????????????addClass(classSet,?packagePath,?packageName);??????????????????????}?else?if?("jar".equals(protocol))?{??
  33. ????????????????????????JarURLConnection?jarURLConnection?=?(JarURLConnection)?url.openConnection();??????????????????????????if?(jarURLConnection?!=?null)?{??
  34. ????????????????????????????JarFile?jarFile?=?jarURLConnection.getJarFile();??????????????????????????????if?(jarFile?!=?null)?{??
  35. ????????????????????????????????Enumeration?jarEntries?=?jarFile.entries();??????????????????????????????????while?(jarEntries.hasMoreElements())?{??
  36. ????????????????????????????????????JarEntry?jarEntry?=?jarEntries.nextElement();??????????????????????????????????????String?jarEntryName?=?jarEntry.getName();??
  37. ????????????????????????????????????if?(jarEntryName.endsWith(".class"))?{??????????????????????????????????????????String?className?=?jarEntryName.substring(0,?jarEntryName.lastIndexOf("."))??
  38. ????????????????????????????????????????????????.replaceAll("/",?".");??????????????????????????????????????????doAddClass(classSet,?className);??
  39. ????????????????????????????????????}??????????????????????????????????}??
  40. ????????????????????????????}??????????????????????????}??
  41. ????????????????????}??????????????????}??
  42. ????????????}??????????}?catch?(Exception?e)?{??
  43. ????????????LOGGER.error("get?class?set?failure.",?e);??????????????throw?new?RuntimeException(e);??
  44. ????????}??????????return?classSet;??
  45. ????}????
  46. ????private?static?void?addClass(Set>?classSet,?String?packagePath,?String?packageName)?{??????????File[]?files?=?new?File(packagePath).listFiles(new?FileFilter()?{??
  47. ????????????public?boolean?accept(File?file)?{??????????????????return?(file.isFile()?&&?file.getName().endsWith(".class"))?||?file.isDirectory();??
  48. ????????????}??????????});??
  49. ????????for?(File?file?:?files)?{??????????????String?fileName?=?file.getName();??
  50. ????????????if?(file.isFile())?{??????????????????String?className?=?fileName.substring(0,?fileName.lastIndexOf("."));??
  51. ????????????????if?(StringUtils.isNotEmpty(packageName))?{??????????????????????className?=?packageName?+?"."?+?className;??
  52. ????????????????}??????????????????doAddClass(classSet,?className);??
  53. ????????????}?else?{??????????????????String?subPackagePath?=?fileName;??
  54. ????????????????if?(StringUtils.isNotEmpty(packageName)){??????????????????????subPackagePath?=?packagePath?+"/"+subPackagePath;??
  55. ????????????????}??????????????????String?subPackageName?=?fileName;??
  56. ????????????????if?(StringUtils.isNotEmpty(packageName)){??????????????????????subPackageName?=?packageName?+"."+subPackageName;??
  57. ????????????????}??????????????????addClass(classSet,subPackagePath,subPackageName);??
  58. ????????????}??????????}??
  59. ????}????
  60. ????private?static?void?doAddClass(Set>?classSet,?String?className)?{??????????Class?cls?=?loadClass(className,?false);??
  61. ????????classSet.add(cls);??????}??
  62. }??






? ? ? ?我们的目标是在控制器类上使用Controller注解,在控制器类的方法上使用Action注解,在服务类上使用Service注解,在控制器类中可以使用Inject注解将服务依赖注入进来。因此我们需要自定义4个注解类。


? ? ? ?控制器类注解代码如下:






[java]
view plain
copy
print
?


  1. package?org.smart4j.framework.annotation;????
  2. import?java.lang.annotation.ElementType;??import?java.lang.annotation.Retention;??
  3. import?java.lang.annotation.RetentionPolicy;??import?java.lang.annotation.Target;??
  4. ??/**?
  5. ?*?Created?by?jack?on?2017/5/22.??*?控制器注解?
  6. ?*/??@Target(ElementType.TYPE)??
  7. @Retention(RetentionPolicy.RUNTIME)??public?@interface?Controller?{??
  8. }??



? ? ? Action方法注解代码如下:





[java]
view plain
copy
print
?


  1. package?org.smart4j.framework.annotation;????
  2. import?java.lang.annotation.ElementType;??import?java.lang.annotation.Retention;??
  3. import?java.lang.annotation.RetentionPolicy;??import?java.lang.annotation.Target;??
  4. ??/**?
  5. ?*?Created?by?jack?on?2017/5/22.??*?Action?方法注解?
  6. ?*/??@Target(ElementType.METHOD)??
  7. @Retention(RetentionPolicy.RUNTIME)??public?@interface?Action?{??
  8. ????/**??????*?请求路径?
  9. ?????*/??????String?value();??
  10. }??






? ? ?服务类注解代码如下:






[java]
view plain
copy
print
?


  1. package?org.smart4j.framework.annotation;????
  2. import?java.lang.annotation.ElementType;??import?java.lang.annotation.Retention;??
  3. import?java.lang.annotation.RetentionPolicy;??import?java.lang.annotation.Target;??
  4. ??/**?
  5. ?*?Created?by?jack?on?2017/5/22.??*?服务类注解?
  6. ?*/??@Target(ElementType.TYPE)??
  7. @Retention(RetentionPolicy.RUNTIME)??public?@interface?Service?{??
  8. }??






? ? ? 依赖注解代码如下:






[java]
view plain
copy
print
?


  1. package?org.smart4j.framework.annotation;????
  2. import?java.lang.annotation.ElementType;??import?java.lang.annotation.Retention;??
  3. import?java.lang.annotation.RetentionPolicy;??import?java.lang.annotation.Target;??
  4. ??/**?
  5. ?*?Created?by?jack?on?2017/5/22.??*?依赖注解类?
  6. ?*/??@Target(ElementType.FIELD)??
  7. @Retention(RetentionPolicy.RUNTIME)??public?@interface?Inject?{??
  8. }??








? ? 由于我们在smart.properties配置文件中指定了


smart.framework.app.base_package

? ?他是整个应用的基础包名,所以我们有必要提供一个ClassHelper助手类,让它分别获取应用包名下的所有的类,应用包名下所有的Service类,应用包名下所有的Controller类。此外可以将带有Controller注解和Service注解的类所产生的对象理解为smart框架所管理的bean,所以有必要在ClassHelper类中增加一个获取应用包名下所有bean类的方法,ClassHelper类的代码如下:


? ? ?





[java]
view plain
copy
print
?


  1. package?org.smart4j.framework.helper;????
  2. import?org.smart4j.framework.annotation.Controller;??import?org.smart4j.framework.annotation.Service;??
  3. import?org.smart4j.framework.org.smart4j.framework.util.ClassUtil;????
  4. import?java.util.HashSet;??import?java.util.Set;??
  5. ??/**?
  6. ?*?Created?by?jack?on?2017/5/22.??*?类操作助手类?
  7. ?*/??public?class?ClassHelper?{??
  8. ????/**??????*?定义类集合,用于存放所加载的类?
  9. ?????*/??????private?static?final?Set>?CLASS_SET;??
  10. ??????static?{??
  11. ????????String?basePackage?=?ConfigHelper.getAppBasePackage();??????????CLASS_SET?=?ClassUtil.getClassSet(basePackage);??
  12. ????}????
  13. ????/**??????*?获取应用包下的所有类?
  14. ?????*/??????public?static?Set>?getClassSet()?{??
  15. ????????return?CLASS_SET;??????}??
  16. ??????/**?
  17. ?????*?获取应用包名下所有Service类??????*/??
  18. ????public?static?Set>?getServiceClassSet()?{??????????Set>?classSet?=?new?HashSet>();??
  19. ????????for?(Class?cls?:?CLASS_SET)?{??????????????if?(cls.isAnnotationPresent(Service.class))?{??
  20. ????????????????classSet.add(cls);??????????????}??
  21. ????????}??????????return?classSet;??
  22. ????}????
  23. ????/**??????*?获取应用包名下所有Controller类?
  24. ?????*/??????public?static?Set>?getControllerClassSet()?{??
  25. ????????Set>?classSet?=?new?HashSet>();??????????for?(Class?cls?:?CLASS_SET)?{??
  26. ????????????if?(cls.isAnnotationPresent(Controller.class))?{??????????????????classSet.add(cls);??
  27. ????????????}??????????}??
  28. ????????return?classSet;??????}??
  29. ????/**??????*?获取应用包名下所有Bean类(包括Service,Controller)?
  30. ?????*/??????public?static?Set>?getBeanClassSet()?{??
  31. ???????Set>?beanClassSet?=?new?HashSet>();?????????beanClassSet.addAll(getServiceClassSet());??
  32. ???????beanClassSet.addAll(getControllerClassSet());??????????return?beanClassSet;??
  33. ????}??}??






? ? ?像上面这样,我们使用ClassHelper封装了ClassUtil,并提供了一系列的助手方法,通过这些方法我们可以直接获取我们想要的类集合,在后面的我们会经常使用到ClassHelper。



友情链接: