如何使用java获取包下被指定注解的类
发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,这篇文章主要介绍如何使用java获取包下被指定注解的类,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!方案一: 采用reflections 框架(此框架依赖com.google.
千家信息网最后更新 2026年11月01日如何使用java获取包下被指定注解的类
这篇文章主要介绍如何使用java获取包下被指定注解的类,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
方案一: 采用reflections 框架(此框架依赖com.google.guava)
1、reflections框架地址:https://github.com/ronmamo/reflections
2、项目依赖
org.reflections reflections 0.9.11 com.google.guava guava 21.0
3、实现代码
//入参 要扫描的包名Reflections f = new Reflections("com.ggband.netty.execute.command");//入参 目标注解类Set
方案二: 采用ClassLoader扫描
1、实现代码
package com.ggband.netty;import java.io.File;import java.io.IOException;import java.lang.annotation.Annotation;import java.net.JarURLConnection;import java.net.URL;import java.net.URLDecoder;import java.util.Enumeration;import java.util.HashSet;import java.util.Set;import java.util.jar.JarEntry;import java.util.jar.JarFile;public class Scanner { /** * 从包package中获取所有的Class * * @param packageName * @return */ public Set> getClasses(String packageName) throws Exception { // 第一个class类的集合 //List> classes = new ArrayList>(); Set> classes = new HashSet<>(); // 是否循环迭代 boolean recursive = true; // 获取包的名字 并进行替换 String packageDirName = packageName.replace('.', '/'); // 定义一个枚举的集合 并进行循环来处理这个目录下的things Enumeration dirs; try { dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName); // 循环迭代下去 while (dirs.hasMoreElements()) { // 获取下一个元素 URL url = dirs.nextElement(); // 得到协议的名称 String protocol = url.getProtocol(); // 如果是以文件的形式保存在服务器上 if ("file".equals(protocol)) { // 获取包的物理路径 String filePath = URLDecoder.decode(url.getFile(), "UTF-8"); // 以文件的方式扫描整个包下的文件 并添加到集合中 addClass(classes, filePath, packageName); } else if ("jar".equals(protocol)) { // 如果是jar包文件 // 定义一个JarFile JarFile jar; try { // 获取jar jar = ((JarURLConnection) url.openConnection()).getJarFile(); // 从此jar包 得到一个枚举类 Enumeration entries = jar.entries(); // 同样的进行循环迭代 while (entries.hasMoreElements()) { // 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件 JarEntry entry = entries.nextElement(); String name = entry.getName(); // 如果是以/开头的 if (name.charAt(0) == '/') { // 获取后面的字符串 name = name.substring(1); } // 如果前半部分和定义的包名相同 if (name.startsWith(packageDirName)) { int idx = name.lastIndexOf('/'); // 如果以"/"结尾 是一个包 if (idx != -1) { // 获取包名 把"/"替换成"." packageName = name.substring(0, idx).replace('/', '.'); } // 如果可以迭代下去 并且是一个包 if ((idx != -1) || recursive) { // 如果是一个.class文件 而且不是目录 if (name.endsWith(".class") && !entry.isDirectory()) { // 去掉后面的".class" 获取真正的类名 String className = name.substring(packageName.length() + 1, name.length() - 6); try { // 添加到classes classes.add(Class.forName(packageName + '.' + className)); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } } } } catch (IOException e) { e.printStackTrace(); } } } } catch (IOException e) { e.printStackTrace(); } return classes; } public void addClass(Set> classes, String filePath, String packageName) throws Exception { File[] files = new File(filePath).listFiles(file -> (file.isFile() && file.getName().endsWith(".class")) || file.isDirectory()); assert files != null; for (File file : files) { String fileName = file.getName(); if (file.isFile()) { String classsName = fileName.substring(0, fileName.lastIndexOf(".")); if (!packageName.isEmpty()) { classsName = packageName + "." + classsName; } doAddClass(classes, classsName); } } } public void doAddClass(Set> classes, final String classsName) throws Exception { ClassLoader classLoader = new ClassLoader() { @Override public Class> loadClass(String name) throws ClassNotFoundException { return super.loadClass(name); } }; classes.add(classLoader.loadClass(classsName)); } public Set> getAnnotationClasses(String packageName, Class annotationClass) throws Exception { //找用了annotationClass注解的类 Set> controllers = new HashSet<>(); Set> clsList = getClasses(packageName); if (clsList != null && clsList.size() > 0) { for (Class> cls : clsList) { if (cls.getAnnotation(annotationClass) != null) { controllers.add(cls); } } } return controllers; }} 2、使用:
Set
扩充:现在就可以实现自己的业务了,比如 扫描com.ggband.netty.execute.command包下被Cmd注解的类 得到Cmd注解value和被注解类的实例
MapbeanContainer = new HashMap<>(); try { //@1 采用reflections 框架(此框架依赖com.google.guava)// Reflections f = new Reflections("com.ggband.netty.execute.command");// Set > set = f.getTypesAnnotatedWith(Cmd.class); //@2 采用ClassLoader扫描 Set > set = new Scanner().getAnnotationClasses("com.ggband.netty.execute.command", Cmd.class); for (Class> c : set) { Object bean = c.newInstance(); Cmd annotation = c.getAnnotation(Cmd.class); beanContainer.put(Arrays.toString(annotation.value()), (Command) bean); } } catch (Exception e) { e.printStackTrace(); }
以上是"如何使用java获取包下被指定注解的类"这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注行业资讯频道!
注解
文件
框架
循环
迭代
目录
代码
内容
方案
篇文章
相同
业务
价值
元素
兴趣
前半部
名字
名称
地址
字符
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
华服互联网科技靠谱吗
互联网科技公司华为
奇酷互联网科技公司
兼蜜互联网科技
互联网科技视频素材
居家互联网科技有限公司
无锡溥仪互联网科技有限公司
字节跳动和互联网科技
互联网校园科技培训
科技互联网大厂
崇明区互联网教育科技诚信经营
民营互联网公司国防科技
特约风豹互联网科技为什么扣费
合肥互联网科技公司公章图片
南通创西澳互联网科技有限公司
互联网科技实习生岗位
四川互联网展示科技馆设计
工业互联网科技创业
互联网时代科技型公司的机会
广州智享互联网科技
什么是科技互联网
互联网金融 科技金融
互联网科技公司电话
智慧科技互联网
四川狮子座互联网科技
互联网金融科技公司干啥的
燊美集互联网科技有限公司
浙南科技城互联网大厦建设工程
翼展科技 首家互联网医院
六子台科技互联网展会