• java读取指定package下的所有class


     JAVA如何扫描一个包下面的所有类,并加载到内存中去?

    spring中有一个<context:component-scan base-package="com.controller"/> 
    意思是说把com.controller包下面的所有类扫描出来。 

    我现在也想做这样的功能 
    把com.controller下面所有类全部扫描出来,并加载到内存中去 
    比如说com.controller下面有三个类 
    com.controller.A 
    com.controller.B 
    com.controller.C 
    ...... 

    我想扫描出这三个类,然后 
    Class ca = Class.forName("com.controller.A"); 
    Class cb = Class.forName("com.controller.B"); 
    Class cc = Class.forName("com.controller.C"); 
    ... 

    List list = new ArrayList(); 
    list.add(ca); 
    list.add(cb); 
    list.add(cc); 
    ...

     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     }  
     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     }  
  • 相关阅读:
    Com组件的两种复用方式:包容与集合的区别
    LAPACK/CLAPACK超级无敌算法库
    转:.h头文件 .lib库文件 .dll动态链接库文件关系
    python中类的变量与对象的变量
    重温:Martin Fowler的持续集成
    转:OOD的五个设计原则
    文章资源分享
    代码奔腾 Code Rush
    非ie6、ie7和ie8中iframe在dom中位置改变会引起iframe的指向重新加载
    前端开发利器webStorm
  • 原文地址:https://www.cnblogs.com/atom-wangzh/p/8797458.html
Copyright © 2020-2023  润新知