Java类自动扫描功能的实现

我们在使用Spring时可以指定一个名包,Spring可以自动扫描出该包下的所有组件。通过翻阅Spring源码,其实这个功能不难实现。

首先,所有在classpath下的资源(文件),都是可以被ClassLoader加载的。我们可以调用它的getResources()方法加载类路径下的文件:

public Enumeration<URL> getResources(String name)
                              throws IOException

这个方法返回一个Enumeration对象,以URL对象的形式保存了路径name下的所有资源。 如果我们传递一个包路径cn/fh, :

ClassLoader cl = Thread.currentThread().getContextClassLoader();

        Enumeration<URL> urls = cl.getResources("cn/fh");
        while (urls.hasMoreElements()) {
            URL u = urls.nextElement();
            System.out.println(u);
            System.out.println(u.getProtocol());
            System.out.println(u.getPath());
        }

则有以下输出结果:

file:/Users/whf/projects/exam/out/production/exam/cn/fh/
file
/Users/whf/projects/exam/out/production/exam/cn/fh/

这是cn/fh不在JAR包中的结果。如果是在JAR包中,则输出以下信息:

jar:file:/Users/whf/.m2/repository/cn/fh/web-security/2.1.1.RELEASE/web-security-2.1.1.RELEASE.jar!/cn/fh/
jar
file:/Users/whf/.m2/repository/cn/fh/web-security/2.1.1.RELEASE/web-security-2.1.1.RELEASE.jar!/cn/fh/

由此, 我们可以得出扫描功能的思路:

1. 调用ClassLoader#getResources()方法,得到返回的URL集合

2. 遍历所有URL对象。

3. 如果是文件,则通过文件I/O操作遍历该目录下所有*.class文件,提取出类名。

4. 如果是Jar包,则通过Jar包I/O操作遍历该Jar包,提取出包中所有*.class文件。

根据以上思路,我们可以写一个PkgScanner类,并提供以下使用方法:

PkgScanner scanner = new PkgScanner("cn.fh.pkgscanner");
    List<String> list = scanner.scan();

    list.forEach( f -> System.out.println(f));

输出:

cn.fh.pkgscanner.PathUtils
cn.fh.pkgscanner.PkgScanner
cn.fh.pkgscanner.ResourceType

完整的实现在github:https://github.com/wanghongfei/pkg-scanner

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-07 00:59:39

Java类自动扫描功能的实现的相关文章

jvm系列(一):java类的加载机制

java类的加载机制 原文:http://www.cnblogs.com/ityouknow/p/5603287.html 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构.类的加载的最终产品是位于堆区中的Class对象,Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口. 类加载器并不需要等到某个

【Java EE 学习 21 下】【 使用易宝支付接口实现java网上支付功能】

一.网上支付分为两种情况,一种方法是使用直接和银行的支付接口,另外一种方法是使用第三方支付平台和银行对接完成支付. 1.直接和银行对接. 2.使用第三方支付平台 3.常见的第三方支付平台 二.使用易宝支付接口实现java网上支付功能(农业银行). 1.完整源代码:https://github.com/kdyzm/day21_2_pay 2.实现过程的时序图 3.技术要点 (1)使用GET请求的时候必须将全部参数都带上,参数名称参考开发者文档中的请求参数列表 (2)使用PaymentUtil类实现

java类中调用servlet

一.Java中调用servlet说明: 我们有时可能需要在Java类中调用Servlet从而实现某些特殊的功能,在JavaAPI中提供了一个URL的类,其中openStream( )方法可以打开URL的连接,并返回一个用于该连接读入的InputStream. 二.Java中调用servlet应用举例: package com.solid.test; import java.io.BufferedReader; import java.io.IOException; import java.io.

java类,对象,方法

1,类和对象   在面向对象的概念当中,类(class)是既包括数据又包括作用于数据的一组操作的封装体.类的数据称为成员变量,类对数据的操作称为成员方法.成员变量反映类的状态和特征,成员方法反映类的行为和能力.类的成员变量和方法统称为类的成员.   对象(Object)是类的实例(instance).对象是动态的,拥有生命周期,都会经历一个从创建.运行到消亡的过程.对象与类的关系就像变量与数据类型一样.   类声明 { 修饰符 } class <Classname> { extends <

JSP-讲解(生成java类、静态导入与动态导入)

一.JSP技术简介 JSP是Java Server Page的缩写,它是Servlet的扩展,它的作用是简化网站的创建和维护. JSP是HTML代码与Java代码的混合体. JSP文件通常以JSP或JSPX的扩展名. JSP拥有自己的语法. JSP形式上像HTML,但本质上是Servlet. JSP的出现,使得将Web开发中的HTML与业务逻辑代码有效分离成为可能.通常JSP只负责生成动态的HTML文档,而业务逻辑由其他Java组件如JavaBean来实现.JSP可以通过Scriptlet来访问

java类和对象基础题2

创建一个三角形类,成员变量三边,方法求周长,创建类主类A来测试它. import java.util.*; public class Sanjiao { private double a,b,c; private double n=a+b+c; public Sanjiao(double a, double b, double c) { super(); this.a = a; this.b = b; this.c = c; } public double getA() { return a;

java 类的匿名类和封装

/* 匿名对象:没有引用类型变量指向的对象称作为匿名对象. 需求: 使用 java类描述一个学生类. 匿名对象要注意的事项: 1. 我们一般不会给匿名对象赋予属性值,因为永远无法获取到. 2. 两个匿名对象永远都不可能是同一个对象. 匿名对象好处:简化书写.可以尽快释放对象的堆内存空间 匿名对象的应用场景: 1. 如果一个对象需要调用一个方法一次的时候,而调用完这个方法之后,该对象就不再使用了,这时候可以使用 匿名对象. 2. 可以作为实参调用一个函数. */ //学生类 class Stude

Java 类反射机制分析

一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.在计算机科学领域,反射是一类应用,它们能够自描述和自控制.这类应用通过某种机制来实现对自己行为的描述和检测,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义. 在Java中的反射机制,被称为Reflection.(大家看到这个单词,第一个想法应该就是去开发文档中搜一下了.)它允许运行中的Java程序对自身进行检查,并能直接操作程序的内部属性或方法.Reflection机制

javap -- Java 类文件解析器

参考文档 http://blog.chinaunix.net/uid-692788-id-2681132.html http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javap.html 功能说明:Java 类文件解析器. 语法:javap [ 命令选项 ] class. . . 补充说明: javap 命令用于解析类文件.其输出取决于所用的选项.若没有使用选项,javap 将输出传递给它的类的 public 域及方法.ja