`
m310851010
  • 浏览: 1668 次
文章分类
社区版块
存档分类
最新评论

扫描Class文件的方法

    博客分类:
  • java
阅读更多

看了别人的代码多了,总能够学习一些东西的,把自己学的东西都点滴都记录下来.

今天自己以前写的一个简单的工具包,用来扫描类,可以扫描jar文件和包里的文件,说明如下:


1.扫描是某子类的Class,可以是包及其子包下的Class包括jar文件里的Class
2.扫描类上含有某(可以是多个)注解的Class,可以是包及其子包下的Class包括jar文件里的Class

 

直接贴部分代码吧:

 

还有其他依赖的类,由于篇幅原因就不贴出来了,下面说说怎么使用吧

 

 

public class ResolverUtil<T> {
  /*
   * An instance of Log to use for logging in this class.
   */
  private static final Logger log = LoggerFactory.getLogger(ResolverUtil.class);

  /**
   * A simple interface that specifies how to test classes to determine if they
   * are to be included in the results produced by the ResolverUtil.
   */
  public static interface Test {
    /**
     * Will be called repeatedly with candidate classes. Must return True if a class
     * is to be included in the results, false otherwise.
     */
    boolean matches(Class<?> type);
  }

  /**
   * A Test that checks to see if each class is assignable to the provided class. Note
   * that this test will match the parent type itself if it is presented for matching.
   */
  public static class IsA implements Test {
    private Class<?> parent;

    /** Constructs an IsA test using the supplied Class as the parent class/interface. */
    public IsA(Class<?> parentType) {
      this.parent = parentType;
    }

    /** Returns true if type is assignable to the parent type supplied in the constructor. */
    public boolean matches(Class<?> type) {
      return type != null && parent.isAssignableFrom(type);
    }

    @Override
    public String toString() {
      return "is assignable to " + parent.getSimpleName();
    }
  }

  /**
   * A Test that checks to see if each class is annotated with a specific annotation. If it
   * is, then the test returns true, otherwise false.
   */
  public static class AnnotatedWith implements Test {
    private Class<? extends Annotation> annotation;

    /** Constructs an AnnotatedWith test for the specified annotation type. */
    public AnnotatedWith(Class<? extends Annotation> annotation) {
      this.annotation = annotation;
    }

    /** Returns true if the type is annotated with the class provided to the constructor. */
    public boolean matches(Class<?> type) {
      return type != null && type.isAnnotationPresent(annotation);
    }

    @Override
    public String toString() {
      return "annotated with @" + annotation.getSimpleName();
    }
  }

  /** The set of matches being accumulated. */
  private Set<Class<? extends T>> matches = new HashSet<Class<? extends T>>();

  /**
   * The ClassLoader to use when looking for classes. If null then the ClassLoader returned
   * by Thread.currentThread().getContextClassLoader() will be used.
   */
  private ClassLoader classloader;

  /**
   * Provides access to the classes discovered so far. If no calls have been made to
   * any of the {@code find()} methods, this set will be empty.
   *
   * @return the set of classes that have been discovered.
   */
  public Set<Class<? extends T>> getClasses() {
    return matches;
  }

  public ClassLoader getClassLoader() {
    return classloader == null ? Thread.currentThread().getContextClassLoader() : classloader;
  }

  public void setClassLoader(ClassLoader classloader) {
    this.classloader = classloader;
  }

  public ResolverUtil<T> findImplementations(Class<?> parent, String... packageNames) {
    if (packageNames == null)
      return this;

    Test test = new IsA(parent);
    for (String pkg : packageNames) {
      find(test, pkg);
    }

    return this;
  }


  public ResolverUtil<T> findAnnotated(Class<? extends Annotation> annotation, String... packageNames) {
    if (packageNames == null)
      return this;

    Test test = new AnnotatedWith(annotation);
    for (String pkg : packageNames) {
      find(test, pkg);
    }

    return this;
  }

  public ResolverUtil<T> find(Test test, String packageName) {
    String path = getPackagePath(packageName);

    try {
      List<String> children = VFS.getInstance().list(path);
      for (String child : children) {
        if (child.endsWith(".class"))
          addIfMatching(test, child);
      }
    } catch (IOException ioe) {
      log.error("Could not read package: " + packageName, ioe);
    }

    return this;
  }

 
  public ResolverUtil<T> find(String packageName, Test test) {
	  return find(test, packageName);
  }
  
  public ResolverUtil<T> find(String packageName, Test ...test) {
    String path = getPackagePath(packageName);

    try {
      List<String> children = VFS.getInstance().list(path);
      for (String child : children) {
        if (child.endsWith(".class"))
          addIfMatching(child, test);
      }
    } catch (IOException ioe) {
      log.error("Could not read package: " + packageName, ioe);
    }

    return this;
  }
  
 
  protected String getPackagePath(String packageName) {
    return packageName == null ? null : packageName.replace('.', '/');
  }

  @SuppressWarnings("unchecked")
  protected void addIfMatching(Test test, String fqn) {
    try {
      String externalName = fqn.substring(0, fqn.indexOf('.')).replace('/', '.');
      ClassLoader loader = getClassLoader();
      log.debug("Checking to see if class " + externalName + " matches criteria [" + test + "]");

      Class<?> type = loader.loadClass(externalName);
      if (test.matches(type)) {
        matches.add((Class<T>) type);
      }
    } catch (Throwable t) {
      log.warn("Could not examine class '" + fqn + "'" + " due to a " +
          t.getClass().getName() + " with message: " + t.getMessage());
    }
  }
  
  @SuppressWarnings("unchecked")
  protected void addIfMatching( String fqn, Test ...test) {
	  try {
		  String externalName = fqn.substring(0, fqn.indexOf('.')).replace('/', '.');
		  ClassLoader loader = getClassLoader();
		  log.debug("Checking to see if class " + externalName + " matches criteria [" + test + "]");
		  
		  Class<?> type = loader.loadClass(externalName);
		  boolean flag = false;
		  for (int i = 0; i < test.length; i++) {
			  if (test[i].matches(type)) {
				  flag = true;
				  break;
			  }
		  }
		  if(flag){
			  matches.add((Class<T>) type);
		  }
	  } catch (Throwable t) {
		  log.warn("Could not examine class '" + fqn + "'" + " due to a " +
				  t.getClass().getName() + " with message: " + t.getMessage());
	  }
  }
}

 

 

public static void main(String[] args) {
		Set<Class<? extends Class<?>>> typeSet = null;
		ResolverUtil<Class<?>> resolverUtil = new ResolverUtil<Class<?>>();
		
		//1.扫描org下的类Class,包括jar包里的Class
		resolverUtil.find(new ResolverUtil.IsA(Object.class), "org.slf4j");
		typeSet = resolverUtil.getClasses();
		System.out.println(typeSet);
		
		//2.以单个个注解方式扫描Class
		resolverUtil.findAnnotated(javax.annotation.Resource.class, "org.mdc");
		typeSet = resolverUtil.getClasses();
		System.out.println(typeSet);
		
		//3.以多个注解方式扫描Class
		resolverUtil.find("org.mdc", new ResolverUtil.AnnotatedWith(javax.annotation.Resource.class), new ResolverUtil.AnnotatedWith(javax.xml.ws.WebFault.class));
		typeSet = resolverUtil.getClasses();
		System.out.println(typeSet);
		
		
	}

 

分享到:
评论

相关推荐

    Spring EntityManager 不能扫描jar 中的class文件

    然而,有时在尝试使用Spring管理持久层时,可能会遇到一个问题:“Spring EntityManager 不能扫描jar中的class文件”。这个问题通常出现在使用Spring自动扫描机制来查找并加载JPA实体类时,如果这些实体类位于外部的...

    classgraph,一个Uber快速、超轻量级Java类路径扫描器、模块扫描仪和注释处理器。.zip

    ClassGraph是一款强大的开源Java工具,它作为一个快速、超轻量级的类路径扫描器、模块扫描仪和注释处理器,广泛应用于各种Java开发场景。这个工具由Luke Daley开发,旨在提供灵活、高效且功能丰富的类扫描解决方案。...

    ClassGraph-超快速超轻量级并行化的Java类路径扫描程序

    ClassGraph的核心功能是扫描Java类路径,包括JAR文件、目录和模块。它能够遍历所有的类、接口、枚举、注解等,查找指定的类或具有特定属性的类。这在处理大型项目或依赖关系时特别有用,例如在运行时检测依赖项、...

    class文件编译利器

    描述中提到的使用方法极其简单:第一步,将这个“class文件编译利器”放置在待反编译的`.class`文件所在的目录下;第二步,直接双击运行该工具,它会自动扫描并处理目录下的所有`.class`文件,生成对应的源代码文件...

    java实现自动扫描文件夹txt文档插入数据库

    在本例中,我们可以通过`File`类的`listFiles()`方法获取指定文件夹下的所有文件。配合`FileFilter`或`FilenameFilter`接口,我们可以筛选出满足特定条件(如.txt扩展名)的文件。 接着,我们需要处理TXT文档的内容...

    JavaClass文件的结构分析及其校验.pdf

    ### JavaClass文件的结构分析及其校验 #### 引言 随着Java技术的不断发展与广泛应用,JavaClass文件作为Java程序的基础组成部分,其结构与验证机制的重要性日益凸显。本文旨在深入探讨JavaClass文件的结构特点,并...

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

    在Spring框架中,动态扫描和注册JavaBean是一个重要的功能,它允许我们在运行时根据特定条件加载和管理Bean,而无需显式地在配置文件中声明它们。这种灵活性使得应用程序能够更加适应变化的需求和动态环境。 首先,...

    自动拷贝class等文件

    介绍下这个打包工具 把本次你改动的java工程下的文件对应的class文件自动打包,然后热部署发布即可 如果你需要频繁改动java代码,热发布几个文件到服务器上,你会怎么做呢? 没有工具的人会手动拷贝目录 然后到...

    springboot编译jar包后无法扫描子jar包中的注解解决方法

    但是,当我们将A项目打包成一个独立的JAR文件后,启动该JAR文件时却发现无法扫描到B项目中的注解。 具体来说,A项目的目录结构在编译后会变成: ``` +BOOT-INF +classes +lib +META-INF +org.springframework....

    kodao扫描仪控件生成文件

    在IT行业中,扫描仪的控制和文件生成是一个重要的应用场景,特别是在文档管理、图像处理和办公自动化领域。Kodao(科达)是一家知名的影像设备提供商,其提供的扫描仪控件使得开发者可以通过编程来控制扫描仪进行...

    java调用扫描仪

    当我们需要在Java应用中实现与硬件设备交互的功能,如调用扫描仪进行文档扫描,就需要借助特定的库和接口。本篇文章将深入探讨如何在Java环境中调用扫描仪,并提供相关实践示例。 首先,理解Java与硬件设备交互的...

    扫描接口实现类

    `Class.getAnnotations()`和`Method.getAnnotation(Class&lt;? extends Annotation&gt; annotationClass)`分别用于获取类和方法的注解。 7. **优化和缓存**:为了提高性能,类扫描的结果通常会缓存起来,避免重复扫描。...

    class.getMethods()

    3. **元数据分析**:分析类的方法结构,进行性能优化、代码质量检查或者生成文档。 在给定的标签"源码"和"工具"中,我们可以推断这个话题可能涉及对Java源码的理解以及在实际工具或框架中的应用。例如,在Struts...

    Java常用工具类UtilClass

    在Java编程中,工具类(Util Class)是包含各种实用函数的静态类,它们提供了一种简化常见任务的方法。在给定的`UtilClass`中,我们有五个主要的工具类:`StringUtil`、`FileUtil`、`ConnectDB`、`DateUtil`和`...

    Android 扫描音频文件.doc

    `scanAudioFile()` 方法触发扫描,`parseSongInfo()` 方法利用 `MediaMetadataRetriever` 获取文件的元数据并填充 `Song` 对象。注意,`MediaMetadataRetriever` 提供的 `extractMetadata()` 方法用于获取元数据,但...

    扫描jar包工具

    java -jar jarscan.jar 查看help信息,可以快速扫描目标文件夹下jar包所包含的class文件相关信息

    Android-Android扫描SD卡指定类型文件

    在Android平台上,对SD卡进行特定类型的文件扫描是一项常见的任务,比如用户可能希望找到所有的.mp3音乐文件或.mp4视频文件。在这个场景中,我们主要会涉及到以下几个Android开发中的关键知识点: 1. **读写权限**...

    java控制扫描仪控件(附:程序源代码)

    本源代码包括:TestJTwain.java,...src.jar里面,所有的.class文件都封装在demo.jar里面,只要当做.rar文件解压就可以看到源代码,此控件不用安装,运行LaunchDemo.bat,就能调用计算机里面的所有twain扫描设备源!

    C#中调用扫描仪示例

    WIA是微软提供的一种用于图像和文档扫描、摄像机和数字相机等设备的编程接口,而TWAIN是一种更通用的标准,被许多扫描仪和摄像头制造商所采用。下面我们将详细讨论如何在C#中使用这两种方法进行扫描仪操作。 1. ...

Global site tag (gtag.js) - Google Analytics