直接上代码,代码依赖tomcat的tomcat-coyote.jar。

package guojje.tools;

import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.apache.tomcat.util.bcel.classfile.AnnotationEntry;
import org.apache.tomcat.util.bcel.classfile.ClassFormatException;
import org.apache.tomcat.util.bcel.classfile.ClassParser;
import org.apache.tomcat.util.bcel.classfile.JavaClass;

public class ScanAnnotations {
    public static void main(String[] args) throws ClassFormatException,
            IOException {
        File dir = null;
        if (args.length > 0) {
            dir = new File(args[0]);
        } else {
            dir = new File(".");
        }

        File[] jarFiles = dir.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return name.endsWith(".jar");
            }
        });
        
        List<File> classFiles =  new LinkedList<File>();
        Queue<File> fileQueue = new LinkedList<File>();    
        fileQueue.offer(dir);
        File curFile = null;
        
        while ((curFile = fileQueue.poll()) != null) {
            File[] subFiles = curFile.listFiles();
            for (File sub : subFiles) {
                if (sub.isDirectory()) {
                    fileQueue.offer(sub);
                } else if (sub.getName().endsWith(".class")) {
                    classFiles.add(sub);
                }
            }
        }
        for (File jf : jarFiles) {
            System.out.println(jf.getName());
            JarFile jarFile = new JarFile(jf);
            scanJarAnnotaiton(jarFile);
        }

        for (File cf : classFiles) {
            System.out.println("===" + cf.getAbsolutePath() + "===================");
            scanClassFileAnnotaiton(cf);
        }
    }

    public static void scanJarAnnotaiton(JarFile jarFile) throws IOException {
        Enumeration<JarEntry> ej = jarFile.entries();
        while (ej.hasMoreElements()) {
            JarEntry je = ej.nextElement();
            if (!je.isDirectory() && je.getName().endsWith(".class")) {
                InputStream classStream = jarFile.getInputStream(je);
                ClassParser classParser = new ClassParser(classStream);
                JavaClass jc = classParser.parse();
                if (jc.getAnnotationEntries() != null
                        && jc.getAnnotationEntries().length > 0) {
                    System.out.println("===" + jarFile.getName() + "======="
                            + jc.getClassName() + "=========================");

                    for (AnnotationEntry ae : jc.getAnnotationEntries()) {
                        System.out.println(ae.getAnnotationType());
                    }
                }
            }
        }
    }

    public static void scanClassFileAnnotaiton(File cf) throws IOException {
        if (!cf.isDirectory() && cf.getName().endsWith(".class")) {
            InputStream classStream = new FileInputStream(cf);
            ClassParser classParser = new ClassParser(classStream);
            JavaClass jc = classParser.parse();
            if (jc.getAnnotationEntries() != null
                    && jc.getAnnotationEntries().length > 0) {
                System.out.println("===" + cf.getAbsolutePath() + "=================");

                for (AnnotationEntry ae : jc.getAnnotationEntries()) {
                    System.out.println(ae.getAnnotationType());
                }
            }
        }

    }
}