如何使用java获取包下被指定注解的类
发表于:2025-11-20 作者:千家信息网编辑
千家信息网最后更新 2025年11月20日,这篇文章主要介绍如何使用java获取包下被指定注解的类,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!方案一: 采用reflections 框架(此框架依赖com.google.
千家信息网最后更新 2025年11月20日如何使用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安全错误
数据库的锁怎样保障安全
中成药传统方剂交叉检索数据库
文章阅读软件开发
加机器人一直被服务器踢出
方舟mts服务器怎么加入
网络安全主要包括那四个方面
区块链技术采用什么数据库
软件开发合同双方争议
公安部网络安全监察举报网址
数据库怎么与软件连接的
我的手机无法连接到服务器咋办
中学网络安全防护毕业论文
数据库查询返回条数
网络安全工程师的自我介绍
dg数据库应用自动切换
数据库的页
数据库几天大小不变化
动态服务器页面技术的特点有哪些
软件开发当前形势
软件服务器没有开启或意外退出
ios淘宝服务器
如何理解维护国家网络安全的意义
中电云网络技术有限公司
河南通用软件开发联系方式
石家庄瑞淘网络技术公司
材料力学软件开发
dxcad用什么软件开发的
js登录本地数据库吗
企业网络安全需要关注什么
数据库管理系统的预处理功能
部队有网络安全课吗