包扫描

我们这篇博文要做的事,就是将com.mec.study包下的类,都扫描显示出来。
在这里插入图片描述
写一个 Scanner.java类 用于实现扫描

import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Enumeration;

public class Scanner
{
    private static void dealClass(Class<?> klass)
    {

    }

    private static void scanDirectory(File curFile, String packageName)
    {
        File[] files=curFile.listFiles();
        for(File file : files)
        {
            // 如果是类的话
            if(file.isFile())
            {
                String fileName=file.getName();
                if(fileName.endsWith(".class"))
                {
                    String className=packageName + "." + fileName.replace(".class", "");
                    System.out.println(className);

                    try
                    {
                        Class<?> klass=Class.forName(className);
                        dealClass(klass);
                    }
                    catch(ClassNotFoundException e)
                    {
                        e.printStackTrace();
                    }
                }
            }
            // 如果是包的话
            else
            {
                // TODO 进入到下一层目录(包),递归扫描
            }
            // 缺乏分辨 包名 和 类名
            // System.out.println(file.getName());// file.getName()
        }
    }

    public static void main(String[] args)
    {
        String packageName="com.mec.Demo";
        String packName=packageName.replace(".", "/");
        System.out.println(packName);

        // ClassLoader的具体作用就是将class文件加载到jvm虚拟机中去; 当前线程的类加载器
        ClassLoader classLoader=Thread.currentThread().getContextClassLoader();

        try
        {
            // 希望得到url(资源定位器)的集合,
            Enumeration<URL> urls=classLoader.getResources(packName);// 导这个 import java.net.URL;
            while(urls.hasMoreElements())
            {
                URL url=urls.nextElement();
                File file=new File(url.toURI());
                // TODO扫描file下的所有文件
                scanDirectory(file, packageName);
                // System.out.println(file.getName());
            }
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
        catch(URISyntaxException e)
        {
            e.printStackTrace();
        }

    }

}

运行结果
在这里插入图片描述
我们可以将 包扫描 弄成专属于我们的工具包 PackageScanner.java ,就像xml解析工具那样。如下

import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Enumeration;

public abstract class PackageScanner
{
    public PackageScanner()
    {
        // TODO 自动生成的构造函数存根
    }

    public abstract void dealClass(Class<?> klass);

    private void dealPackage(File cur, String packageName)
    {
        File[] files=cur.listFiles();
        for(File file : files)
        {
            // 如果是类的话
            if(file.isFile())
            {
                String fileName=file.getName();
                if(!fileName.endsWith(".class"))
                {
                    continue;
                }
                fileName=fileName.replace(".class", "");
                String className=packageName + "." + fileName;

                try
                {
                    Class<?> klass=Class.forName(className);
                    dealClass(klass);
                }
                catch(ClassNotFoundException e)
                {
                    e.printStackTrace();
                }
            }
            // 如果是包的话
            else
            {
                // TODO 进入到下一层目录(包),递归扫描
                dealPackage(file, packageName + "." + file.getName());
            }
            // 缺乏分辨 包名 和 类名
            // System.out.println(file.getName());// file.getName()
        }
    }

    public void scanPackage(String packageName)
    {

        // ClassLoader的具体作用就是将class文件加载到jvm虚拟机中去; 当前线程的类加载器
        ClassLoader classLoader=Thread.currentThread().getContextClassLoader();
        String packName=packageName.replace(".", "/");

        try
        {
            // 希望得到url(资源定位器)的集合,
            Enumeration<URL> urls=classLoader.getResources(packName);// 导这个 import java.net.URL;
            while(urls.hasMoreElements())
            {
                URL url=urls.nextElement();
                File curfile=new File(url.toURI());
                // TODO扫描file下的所有文件
                dealPackage(curfile, packageName);
                // System.out.println(file.getName());
            }
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
        catch(URISyntaxException e)
        {
            e.printStackTrace();
        }

    }

}

也给出一个使用我们这个工具类的 Test.java

public class Test
{
    public static void main(String[] args)
    {
        new PackageScanner()
        {
            public void dealClass(Class<?> klass)
            {
                if(klass.isPrimitive() || klass.isInterface() || klass.isAnnotation() || klass.isArray() || klass.isEnum())
                {
                    return;
                }
                System.out.println(klass.getName());
            }
        }.scanPackage("com.mec.study");
    }
}

运行结果如下
在这里插入图片描述
上面是实现了我们自己写的包,那该如何扫描jar包呢
需要更改PackageScanner.java中的一点东西,如下

  private void dealJar(URL url)
    {
        try
        {
            JarURLConnection connection=(JarURLConnection) url.openConnection();
            JarFile jarFile=connection.getJarFile();
            Enumeration<JarEntry> entryList=jarFile.entries();
            while(entryList.hasMoreElements())
            {
                JarEntry jarEntry=entryList.nextElement();
                if(jarEntry.isDirectory() || !jarEntry.getName().endsWith(".class"))
                {
                    continue;
                }
                String className=jarEntry.getName();
                className=className.replace(".class", " ");
                className=className.replace("/", ".");
                System.out.println(className);
                // try
                // {
                // Class<?> klass=Class.forName(className);
                // dealClass(klass);
                // }
                // catch(ClassNotFoundException e)
                // {
                // e.printStackTrace();
                // }
            }
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
    }

    public void scanPackage(String packageName)
    {

        // ClassLoader的具体作用就是将class文件加载到jvm虚拟机中去; 当前线程的类加载器
        ClassLoader classLoader=Thread.currentThread().getContextClassLoader();
        String packName=packageName.replace(".", "/");

        try
        {
            // 希望得到url(资源定位器)的集合,
            Enumeration<URL> urls=classLoader.getResources(packName);// 导这个 import java.net.URL;
            while(urls.hasMoreElements())
            {
                URL url=urls.nextElement();
                if(url.getProtocol().equals("jar"))
                {

                    dealJar(url);
                }
                else
                {
                    File curfile;
                    try
                    {
                        curfile=new File(url.toURI());
                        // TODO扫描file下的所有文件
                        dealPackage(curfile, packageName);
                        // System.out.println(file.getName());
                    }
                    catch(URISyntaxException e)
                    {
                        e.printStackTrace();
                    }
                }
            }
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }

    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值