Java学习笔记 —— 指定包名扫描包下所有类并获取相关注解信息

Java学习笔记 —— 指定包下扫描所有类并获取相关注解信息

前言

今天复习了一下注解知识,想到类似与一些 反射包 可以直接扫描包的这个功能,于是乎我花了一点点时间,也做了一个类似功能,有需要的可以了解一下思路

定义注解

annation包


/**
 * 角色
 *
 * @author Marinda
 * @date 2022/10/22
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Role {
    String name();
    String role() default "成员";
}

定义实现类

handle包

User.java

package cn.marinda.handle;

import cn.marinda.annotaion.Role;

public class User {

    @Role(name = "小红",role = "管理员")
    public void xiaoHong(){}

    @Role(name = "小明")
    public void xiaoMing(){}
}

package cn.marinda.handle;

import cn.marinda.annotaion.Role;
import cn.marinda.annotaion.UserAnnotaion;

import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.*;

public class UserHandle {

    public List<Class> getClassListByPackage(String packageName){
//        定义List
        List<Class> classList = new ArrayList<>();
//        获取根目录
        String userDir = System.getProperty("user.dir");
//        获取Src地址
        String srcPath = userDir.concat("/src");
//        File遍历
        File srcFile = new File(srcPath);
//        定义List列表储存包名
        List<File> packageFileList = new ArrayList<>();
//        如果是目录
        getPackageFileList(srcFile,packageFileList);
//        验证是否存在这个包名
        if(!validPackageExists(packageName,packageFileList)){
//            不存在包名
            return null;
        }
//        储存
        Map<String,List<String>> packageMap = new HashMap<>();
//        遍历包文件
        packageFileList.forEach((ele)->{
//            获取包下的class信息
            packageMap.putAll(getPackageClassInfo(ele));
        });

//        开始获取包注解信息
        List<String> classInfo = packageMap.get(packageName);
        queryAnnotaion(classInfo,packageName);
        return null;
    }

    /**
     *  执行
     *
     * @param classInfo   类信息
     * @param packageName 包名
     */
    void queryAnnotaion(List<String> classInfo,String packageName){
//
        String parentPath = "cn.marinda".concat(".".concat(packageName));
        System.out.println("ParentPath: " + parentPath);
        try {
            for (String className : classInfo) {
                String path = parentPath.concat(".".concat(className));
                System.out.println("Path: "+ path);
                Class cl = Class.forName(path);
//                获取方法
                Method[] methods = cl.getDeclaredMethods();
                for (Method method : methods) {
                    Annotation[] annotations = method.getAnnotations();
//                    System.out.println("注解数量:" + annotations.length);
//                    有效注解
                    if(annotations.length > 0){
                      for(Annotation annotation : annotations){
                        if(annotation instanceof Role){
                            Role role = (Role) annotation;
                            System.out.println(String.format("名称:%s, 身份: %s",role.name(),role.role()));
                        }
                    }
                    }
                }
                continue;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 验证包名是否存在
     *
     * @return boolean
     */
    boolean validPackageExists(String packageName,List<File> packageFileList){
        boolean flag = false;
        for (File file : packageFileList) {
            if(file.getName().equalsIgnoreCase(packageName)){
                flag = true;
            }
        }
        return flag;
    }

    /**
     * 递归获取包名列表
     *
     * @param dirFile dir文件
     */
    void getPackageFileList(File dirFile,List<File> packageList){

        for(File listFile : dirFile.listFiles()){
            if(listFile.isDirectory()){
                for (File file : listFile.listFiles()) {
//                    目录下有文件的包名
                    if(file.isFile()){
//                        不添加带有启动类的包
                        if(!file.getName().equalsIgnoreCase("Main.java")){
                            if(!packageList.contains(listFile)){
                                System.out.println("file: " + listFile.getPath());
                                packageList.add(listFile);
                            }
                        }
                        continue;
                    }
                }
            }
//            如果是文件则停止
            if(listFile.isFile()){
                break;
            }
//            递归
            getPackageFileList(listFile,packageList);
        }
    }

    /**
     * 通过包获取类文件名称
     *
     * @param packageFile 包文件
     * @return {@link Map}<{@link String}, {@link String}>
     */
    Map<String,List<String>> getPackageClassInfo(File packageFile){
        Map<String,List<String>> classNameMap = new HashMap<>();
        File file = new File(packageFile.getPath());
        ArrayList list = new ArrayList();
        Arrays.stream(file.listFiles()).forEach((ele)->{
            String className = ele.getName().replace(".java","");
            list.add(className);
            classNameMap.put(packageFile.getName(),list);
        });
        return classNameMap;
    }




    @UserAnnotaion({"你好","我是小明"})
    public void test(){
        try {

            Class<UserHandle> userHandleClass = UserHandle.class;

            Annotation[] annotations = userHandleClass.getAnnotations();
            System.out.println("获取方法的注解数据");
            Method method = userHandleClass.getMethod("test");
            UserAnnotaion annotation = method.getAnnotation(UserAnnotaion.class);
            for(String str : annotation.value()){
                System.out.println("方法注解数据:"+ str);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    @UserAnnotaion({"小明"})
    public void xiaoMing(){

    }
    @UserAnnotaion("小红")
    public void xiaoHong(){

    }
}

运行结果

在这里插入图片描述

温馨提示

该扫描功能实现是来自于File进行监测

结束语

Java学习笔记 —— 指定包名扫描包下所有类并获取相关注解信息

  • 如果对你有帮助的话可以给我点赞收藏,十分感谢
  • 致力做学习笔记分享给大家
  • 可以转载 需标明 出处 本文链接。
  • 笔者一个开源项目:我的世界开服助手 希望大家可以点一下star

感谢你的观看。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值