`

Java扫描指定包中所有类

阅读更多

1. 扫描类

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import com.cnp.andromeda.common.util.StringUtil;

/**
 * @Author
 * @Description 包扫描器
 * @CopyRight 
 */
public class ClassScanner{
    private Map<String, Class<?>> classes           = new HashMap<String, Class<?>>();
    private FilenameFilter        javaClassFilter;                                    // 类文件过滤器,只扫描一级类
    private final String          CLASS_FILE_SUFFIX = ".class";                       // Java字节码文件后缀
    private String                packPrefix;                                         // 包路径根路劲

    public ClassScanner(){
        javaClassFilter = new FilenameFilter(){
            @Override
            public boolean accept(File dir, String name){
                // 排除内部内
                return !name.contains("$");
            }
        };
    }

    /**
     * @Title: scanning
     * @Description 扫描指定包(本地)
     * @param basePath 包所在的根路径
     * @param packagePath 目标包路径
     * @return Integer 被扫描到的类的数量
     * @throws ClassNotFoundException
     */
    public Integer scanning(String basePath, String packagePath) throws ClassNotFoundException{
        packPrefix = basePath;

        String packTmp = packagePath.replace('.', '/');
        File dir = new File(basePath, packTmp);

        // 不是文件夹
        if(dir.isDirectory()){
            scan0(dir);
        }

        return classes.size();
    }

    /**
     * @Title: scanning
     * @Description 扫描指定包, Jar或本地
     * @param packagePath 包路径
     * @param recursive 是否扫描子包
     * @return Integer 类数量
     */
    public Integer scanning(String packagePath, boolean recursive){
        Enumeration<URL> dir;
        String filePackPath = packagePath.replace('.', '/');
        try{
            // 得到指定路径中所有的资源文件
            dir = Thread.currentThread().getContextClassLoader().getResources(filePackPath);
            packPrefix = Thread.currentThread().getContextClassLoader().getResource("").getPath();
            if(System.getProperty("file.separator").equals("\\")){
                packPrefix = packPrefix.substring(1);
            }

            // 遍历资源文件
            while(dir.hasMoreElements()){
                URL url = dir.nextElement();
                String protocol = url.getProtocol();

                if("file".equals(protocol)){
                    File file = new File(url.getPath().substring(1));
                    scan0(file);
                } else if("jar".equals(protocol)){
                    scanJ(url, recursive);
                }
            }
        }
        catch(Exception e){
            throw new RuntimeException(e);
        }

        return classes.size();
    }

    /**
     * @Title: scanJ
     * @Description 扫描Jar包下所有class
     * @param url jar-url路径
     * @param recursive 是否递归遍历子包
     * @throws IOException
     * @throws ClassNotFoundException
     */
    private void scanJ(URL url, boolean recursive) throws IOException, ClassNotFoundException{
        JarURLConnection jarURLConnection = (JarURLConnection)url.openConnection();
        JarFile jarFile = jarURLConnection.getJarFile();

        // 遍历Jar包
        Enumeration<JarEntry> entries = jarFile.entries();
        while(entries.hasMoreElements()){
            JarEntry jarEntry = (JarEntry)entries.nextElement();
            String fileName = jarEntry.getName();

            if (jarEntry.isDirectory()) {
                if (recursive) {
                }
                continue;
            }
            
            // .class
            if(fileName.endsWith(CLASS_FILE_SUFFIX)){
                String className = fileName.substring(0, fileName.indexOf('.')).replace('/', '.');
                classes.put(className, Class.forName(className));
            }

        }
    }

    /**
     * @Title: scan0
     * @Description 执行扫描
     * @param dir Java包文件夹
     * @throws ClassNotFoundException
     */
    private void scan0(File dir) throws ClassNotFoundException{
        File[] fs = dir.listFiles(javaClassFilter);
        for(int i = 0; fs != null && i < fs.length; i++){
            File f = fs[i];
            String path = f.getAbsolutePath();
            
            // 跳过其他文件
            if(path.endsWith(CLASS_FILE_SUFFIX)){
                String className = StringUtil.getPackageByPath(f, packPrefix); // 获取包名
                classes.put(className, Class.forName(className));
            }
        }
    }

    /**
     * @Title: getClasses
     * @Description 获取包中所有类
     * @return Map&lt;String,Class&lt;?&gt;&gt; K:类全名, V:Class字节码
     */
    public Map<String, Class<?>> getClasses(){
        return classes;
    }

    public static void main(String[] args) throws ClassNotFoundException{
        ClassScanner cs = new ClassScanner();
        int c = cs.scanning("W:/IWiFI/Code/trunk/operation/target/classes/", "com/cnp/andromeda/common/util/");
        System.out.println(c);
        System.out.println(cs.getClasses().keySet());

        ClassScanner cs2 = new ClassScanner();
        int c2 = cs2.scanning("com.cnp.swarm", false);
        System.out.println(c2);
        System.out.println(cs2.getClasses().keySet());
    }
}

 

2. 依赖工具类

import java.io.File;

/**
 * @FileName: StringUtil.java
 * @Author 
 * @Description:
 * @Date 2014年11月16日 上午10:04:03
 * @CopyRight 
 */

/**
 * 字符串工具类
 */
public final class StringUtil {

    /**
     * @Title: getMethodName
     * @Description: 获取对象类型属性的get方法名
     * @param propertyName
     *            属性名
     * @return String "get"开头且参数(propertyName)值首字母大写的字符串
     */
    public static String convertToReflectGetMethod(String propertyName) {
        return "get" + toFirstUpChar(propertyName);
    }

    /**
     * @Title: convertToReflectSetMethod
     * @Description: 获取对象类型属性的set方法名
     * @param propertyName
     *            属性名
     * @return String "set"开头且参数(propertyName)值首字母大写的字符串
     */
    public static String convertToReflectSetMethod(String propertyName) {
        return "set" + toFirstUpChar(propertyName);
    }

    /**
     * @Title: toFirstUpChar
     * @Description: 将字符串的首字母大写
     * @param target
     *            目标字符串
     * @return String 首字母大写的字符串
     */
    public static String toFirstUpChar(String target) {
        StringBuilder sb = new StringBuilder(target);
        sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
        return sb.toString();
    }

    /**
     * @Title: getFileSuffixName
     * @Description: 获取文件名后缀
     * @param fileName
     *            文件名
     * @return String 文件名后缀。如:jpg
     */
    public static String getFileSuffixName(String fileName) {
        return fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
    }

    /**
     * 
     * @Title: checkStringIsNotEmpty
     * @Description:验证字符串是否不为空
     * @param stringValue
     *            传入要验证的字符串
     * @return boolean true:不为 空 或 不为null; false:值为 空 或 为null
     */
    public static boolean isNotEmpty(String stringValue) {
        if (null == stringValue || "".equals(stringValue.trim())) {
            return false;
        }
        return true;
    }

    /**   
     * @Title: getPackageByPath   
     * @Description 通过指定文件获取类全名  
     * @param classFile 类文件
     * @return String 类全名
     */
    public static String getPackageByPath(File classFile, String exclude){
        if(classFile == null || classFile.isDirectory()){
            return null;
        }
        
        String path = classFile.getAbsolutePath().replace('\\', '/');

        path = path.substring(path.indexOf(exclude) + exclude.length()).replace('/', '.');
        if(path.startsWith(".")){
            path = path.substring(1);
        }
        if(path.endsWith(".")){
            path = path.substring(0, path.length() - 1);
        }

        return path.substring(0, path.lastIndexOf('.'));
    }
}

 

0
0
分享到:
评论

相关推荐

    通过java的反射技术获取,某个包路径下的类,并以表格形式打印类的属性注解注释及属性名称等

    在给定的场景中,我们需要实现的功能是遍历指定包路径下的所有类,获取它们的属性信息,包括属性的注解和注释,并以表格形式输出。 首先,我们需要通过`Package.getPackage(String name)`方法获取指定包名的Package...

    java端口扫描程序

    Java端口扫描程序是一种利用Java编程语言实现的工具,用于检测特定IP地址上指定范围内端口的开放状态。端口扫描是网络安全评估和系统管理员常用的技术,它可以帮助识别网络服务、漏洞以及潜在的安全风险。 在Java中...

    java扫描图片

    2. **文件I/O操作**: 使用`java.io`包中的`File`类可以获取文件路径,创建和操作文件。在扫描图片时,我们需要创建`File`对象来指定图片的路径,然后使用`exists()`检查文件是否存在,`isFile()`确认是文件而非目录...

    扫描指定包下的class,并将javaBean对象动态注册到spring环境中

    动态扫描包是指程序在运行时能够自动发现并处理指定包及其所有子包中的类。这个过程通常通过Spring的`ClassPathScanningCandidateComponentProvider`类来实现。这个类可以扫描类路径,寻找符合特定条件(例如,具有...

    Java的包扫描实现和Jar应用.docx

    包扫描是一种机制,它允许我们在运行时查找并处理指定包或其子包下的所有类。在Spring框架中,这种机制被广泛用于自动装配和组件扫描,以便在启动时识别和初始化相关的bean。在自定义的项目中,我们也可以利用这个...

    java实现一个扫描包的工具类实例代码

    接下来,我们需要实现包扫描的核心方法`scan(String packageName)`,这个方法会遍历指定包下的所有类。为了处理JAR包中的类,我们需要处理URL并打开JAR文件。这里用到了`File`, `FileFilter`, `JarURLConnection`, `...

    自己写的某网站批量扫描下载指定图片的javaDome,交流一下

    通常,我们会使用`java.nio`包中的文件操作类,如`Files`和`Path`,以及`InputStream`和`OutputStream`来读写文件。这里的关键是正确处理IO流,确保图片数据被完整地写入本地文件。 在批量下载过程中,可能会遇到...

    java SE 类库查询手册

    这份文件是一本关于Java SE类库查询手册的内容摘要,其中详细列出了Java SE 6版本中常用的接口和类,主要集中在以下几个包中:java.applet, java.lang, java.io, 以及java.awt。以下是对文档中提及的知识点的详细...

    java类查找小工具

    3. 扫描jar文件和目录:工具遍历指定的目录,读取每个jar文件的META-INF/MANIFEST.MF文件来获取jar的主类和其他元数据。同时,它还打开jar文件,逐个读取并解析.class文件,查找目标类。 4. 类位置确定:一旦找到...

    java多线程端口扫描器

    Java多线程端口扫描器是一种利用Java编程语言实现的工具,它能够高效地检测一个或多个目标IP地址或计算机名上的开放端口。在网络安全和系统管理领域,端口扫描是常用的技术,用于发现网络服务、识别漏洞或检查安全...

    端口扫描器

    此外,还可以使用`java.nio`包中的非阻塞I/O(NIO)来提高扫描效率,通过异步处理连接请求,允许同时处理多个端口扫描。 这个简单的JAVA端口扫描器项目可能包括以下关键组件: 1. 用户界面:使用SWING构建,包括...

    Java 图形化U盘小偷

    或者,他们可能使用`java.util.concurrent`包中的定时任务,如`ScheduledExecutorService`,每隔一定时间执行一次扫描,检测USB设备的变化。 总体来说,【Java图形化U盘小偷】项目涉及了Java GUI编程、文件操作、...

    北邮Java作业.pdf

    " 语句会导入java.util包中的所有类。在提供的部分内容中,可能包含了对导入语句的错误扫描,但是没有具体的错误声明,所以无法确定扫描错误的具体内容。 2. 类的继承: Java中的继承使用关键字"extends"来实现。...

    Java面试题以及答案整理.pdf

    使用`java.util.Calendar`或`java.time`包中的类来获取昨天的日期,并格式化输出。 18. **文件读写计数器** 使用`java.io`包中的`FileReader`、`BufferedReader`等类进行文件读取,同时维护一个计数器记录行数。 ...

    Feign配置扫描包出现奇葩问题.docx

    因此,要解决Feign配置扫描包出现奇葩问题,需要正确配置Feign客户端,指定fallbackFactory类,启用Feign客户端,并指定要扫描的包。此外,还需要正确配置Spring Boot应用程序,指定要扫描的包,以便Spring Boot应用...

    Java选择题武汉大学JAVA基础.pdf

    Java的I/O处理涉及到读写数据流,包括java.io包中的File、FileReader、FileWriter等类。 18. Java的命令行参数 main方法可以通过String args[]接收命令行参数。 19. Java的继承和多态 通过extends关键字实现类的...

    java类Formatter解析.pdf

    除了Formatter类,文档还提到了java.text包中的多个类,它们都是用于处理不同类型的数据格式化的工具类,包括DateFormat,DecimalFormat,NumberFormat等。其中,DateFormat和SimpleDateFormat类用于日期和时间的...

    浅谈两个jar包中包含完全相同的包名和类名的加载问题

    了解Jar包中的类加载问题 Java中的类加载机制是指Java虚拟机(JVM)在加载类文件时的相关处理过程。当多个Jar包中包含相同的包名和类名时,可能会出现类加载问题。下面我们来讨论这种情况下的类加载问题。 类加载...

    ScanUtil.java

    1. **目录遍历**:该工具类可能会递归遍历指定的目录,查找所有的Java源文件。这涉及到文件系统的操作,如`java.io.File`类的使用。 2. **编译器API**:为了读取和理解Java源代码,`ScanUtil`可能利用了JDK的`javax...

    java记事本.pdf

    - 通过java.io包中的类和接口,如FileWriter、BufferedReader、FileReader等,进行文件的读写操作 5. 多线程编程的简单应用 - Logger类的使用,可以用于记录程序的执行情况和错误日志,这是Java多线程日志记录的...

Global site tag (gtag.js) - Google Analytics