Java扫描classpath指定包路径下所有class

来源:互联网 发布:oracle数据库全库备份 编辑:程序博客网 时间:2024/06/05 20:20

在写框架时 经常需要扫描classpath指定包路径下带有某个Annotation的类,自己整理了一下 封装成一个工具类了,供大家参考。

源代码

ClassPathResourceScanner.java 如下:

package com.bytebeats.jupiter.ioc;import com.bytebeats.jupiter.util.ClassHelper;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.io.File;import java.io.IOException;import java.net.JarURLConnection;import java.net.URL;import java.net.URLDecoder;import java.util.*;import java.util.jar.JarEntry;import java.util.jar.JarFile;import java.util.regex.Pattern;/** * ${DESCRIPTION} * * @author Ricky Fung * @create 2016-12-11 16:02 */public class ClassPathCandidateComponentScanner {    private final Logger logger = LoggerFactory.getLogger(getClass());    public static final String CLASS_SUFFIX = ".class";    private static final Pattern INNER_PATTERN = java.util.regex.Pattern.compile("\\$(\\d+).", java.util.regex.Pattern.CASE_INSENSITIVE);    public Set<Class<?>> findCandidateComponents(String packageName) throws IOException {        if (packageName.endsWith(".")) {            packageName = packageName.substring(0, packageName.length()-1);        }        Map<String, String> classMap = new HashMap<>(32);        String path = packageName.replace(".", "/");        Enumeration<URL> urls = findAllClassPathResources(path);        while (urls!=null && urls.hasMoreElements()) {            URL url = urls.nextElement();            String protocol = url.getProtocol();            if ("file".equals(protocol)) {                String file = URLDecoder.decode(url.getFile(), "UTF-8");                File dir = new File(file);                if(dir.isDirectory()){                    parseClassFile(dir, packageName, classMap);                }else {                    throw new IllegalArgumentException("file must be directory");                }            } else if ("jar".equals(protocol)) {                parseJarFile(url, classMap);            }        }        Set<Class<?>> set = new HashSet<>(classMap.size());        for(String key : classMap.keySet()){            String className = classMap.get(key);            try {                set.add(ClassHelper.forName(className));            } catch (ClassNotFoundException e) {                e.printStackTrace();            }        }        return set;    }    protected void parseClassFile(File dir, String packageName, Map<String, String> classMap){        if(dir.isDirectory()){            File[] files = dir.listFiles();            for (File file : files) {                parseClassFile(file, packageName, classMap);            }        } else if(dir.getName().endsWith(CLASS_SUFFIX)) {            String name = dir.getPath();            name = name.substring(name.indexOf("classes")+8).replace("\\", ".");            System.out.println("file:"+dir+"\t class:"+name);            addToClassMap(name, classMap);        }    }    protected void parseJarFile(URL url, Map<String, String> classMap) throws IOException {        JarFile jar = ((JarURLConnection) url.openConnection()).getJarFile();        Enumeration<JarEntry> entries = jar.entries();        while (entries.hasMoreElements()) {            JarEntry entry = entries.nextElement();            if (entry.isDirectory()) {                continue;            }            String name = entry.getName();            if(name.endsWith(CLASS_SUFFIX)){                addToClassMap(name.replace("/", "."), classMap);            }        }    }    private boolean addToClassMap(String name, Map<String, String> classMap){        if(INNER_PATTERN.matcher(name).find()){ //过滤掉匿名内部类            System.out.println("anonymous inner class:"+name);            return false;        }        System.out.println("class:"+name);        if(name.indexOf("$")>0){ //内部类            System.out.println("inner class:"+name);        }        if(!classMap.containsKey(name)){            classMap.put(name, name.substring(0, name.length()-6)); //去掉.class        }        return true;    }    protected Enumeration<URL> findAllClassPathResources(String path) throws IOException {        if(path.startsWith("/")){            path = path.substring(1);        }        Enumeration<URL> urls = ClassHelper.getClassLoader().getResources(path);        return urls;    }}

使用方法

ClassPathCandidateComponentScanner scanner = new ClassPathCandidateComponentScanner();//要扫描的包名String packageName = "com.bytebeats";//获取该包下所有的类名称Set<Class<?>> set = scanner.findCandidateComponents(packageName);System.out.println(set.size());for (Class<?> cls : set){    System.out.println(cls.getName());}


这方面已经有一些不错的开源项目,例如:
reflections:https://github.com/ronmamo/reflections
Scannotation:http://scannotation.sourceforge.net/

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 代购被海关税了怎么办 网上买猫被骗了怎么办 苏宁账号被冻结怎么办 九州娱乐提款未到账怎么办 法院拍卖后不足的余款怎么办 购车后余款没拿怎么办? 抵押房屋被执行后余款怎么办 苏宁无敌券过期怎么办 被亚马逊自营跟卖怎么办 苏宁易购绑定手机后解绑不了怎么办 手机qq注册号码忘了怎么办 原创头条号被限制推荐了怎么办 为什么打开app有广告怎么办 苹果手机浏览器总是弹出广告怎么办 手机上打开页面出现广告怎么办 电脑下面的任务栏变宽了怎么办 酷派手机总是出现广告怎么办 电脑弹出的热点新闻关闭不了怎么办 京东老是弹广告怎么办 电脑右下角出现无法显示网页怎么办 电脑右下角广告关不了怎么办 qq邮箱被冻结了怎么办 手机qq群自动发广告怎么办 济宁学院考研和上课冲突怎么办 考研但是大四上课多怎么办 试管促排卵泡少怎么办 京东退货卖家拒收怎么办 京东退货被卖家拒收怎么办 期货平台跑路了怎么办 浮云牧场没房了怎么办 融资股票停牌了怎么办 买入的股票停牌怎么办 淘宝抢到便宜货老板不发货怎么办 微信代购买到假货了怎么办 微信代购收到假货怎么办 苹果商店下载很慢怎么办 谷歌商店下载东西慢怎么办 买家说少发货了怎么办 人肉代购被海关扣了怎么办 韩国代购被海关扣了怎么办 爱奇艺开通自动续费忘了账号怎么办