[程序设计]注解开发工具类:根据注解获取其所标记的类、属性和方法

注解开发工具类,主要是根据注解获取对应的类、属性和方法。突然的一个想法做出来,我也不知道有没有用,还有一些想做的功能会在之后慢慢更新。
附Gitee仓库:AnnotationUtils

package pers.LovelyBunny.AnnotationUtils.utils;

import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * 
 * 注解开发工具类
 * 
 * 全局静态方法调用,不需要实例化对象
 * 
 * @author 张泽楠
 * @since 2021-06-18
 * @version 1.0
 * 
 */
public class AnnotationUtils {

	/** 扫描根路径{@value} */
	private static String rootPath;
	/** 类名列表{@value} */
	private static List<String> nameList = new ArrayList<String>();
	/** 注解列表{@value} */
	private static List<Class<Annotation>> annotationList = new ArrayList<Class<Annotation>>();
	/** 类表{注解名: 类}{@value} */
	private static Map<String, List<Class<?>>> classPool = new HashMap<String, List<Class<?>>>();
	/** 接口表{注解名: 接口}{@value} */
	private static Map<String, List<Class<?>>> interfacePool = new HashMap<String, List<Class<?>>>();
	/** 枚举类表{注解名: 枚举类}{@value} */
	private static Map<String, List<Class<?>>> enumPool = new HashMap<String, List<Class<?>>>();
	/** 属性表{注解名: {类名: 属性列表}}{@value} */
	private static Map<String, Map<String, List<Field>>> fieldPool = new HashMap<String, Map<String, List<Field>>>();
	/** 方法表{注解名: {类名: 方法列表}}{@value} */
	private static Map<String, Map<String, List<Method>>> methodPool = new HashMap<String, Map<String, List<Method>>>();

	/**
	 * 程序加载时自动调用初始化函数{@link pers.LovelyBunny.AnnotationUtils.utils.AnnotationUtils#init()}
	 */
	static {
		try {
			init();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 不需要实例化对象
	 */
	private AnnotationUtils() {
		super();
	}

	/**
	 * 
	 * AnnotationUtils初始化
	 * 
	 * @throws Exception
	 */
	private static void init() throws Exception {
		System.out.println("----------------AnnotationUtils init begin----------------");
		// 获取class根路径
		String runModel = AnnotationUtils.class.getResource("").getProtocol();
		// 判断运行模式,扫描包获取所有class的全限定类名,并保存在nameList中
		if ("file" == runModel) {
			rootPath = AnnotationUtils.class.getResource("/").toString().replace("file:/", "").replace("\\", "/");
			scanPackageInFile(new File(rootPath));
		} else if ("jar" == runModel) {
			rootPath = AnnotationUtils.class.getProtectionDomain().getCodeSource().getLocation().getPath();
			scanPackageInJar();
		} else {
			System.out.println("----------------AnnotationUtils init failure----------------");
			return;
		}
		// 根据注解和类对所有class分类
		sortClass();
		System.out.println("----------------AnnotationUtils init finished----------------");
	}

	/**
	 * 
	 * 扫描jar包,获取所有class的全限定类名
	 * 
	 * @throws IOException
	 */
	private static void scanPackageInJar() throws IOException {
		JarFile jarFile = new JarFile(new File(rootPath));
		Enumeration<JarEntry> entrys = jarFile.entries();
		while (entrys.hasMoreElements()) {
			JarEntry jar = entrys.nextElement();
			String name = jar.getName();
			if (name.endsWith(".class")) {
				nameList.add(name.replace("\\", "/").replace(".class", "").replace("/", "."));
			}
		}
		jarFile.close();
	}

	/**
	 * 
	 * 递归扫描包,获取所有class的全限定类名
	 * 
	 * @param nodeFile
	 *            递归节点文件
	 * @throws Exception
	 */
	private static void scanPackageInFile(File nodeFile) throws Exception {
		File[] filesList = nodeFile.listFiles();
		for (File file : filesList) {
			if (file.isDirectory()) {
				scanPackageInFile(file);
			} else {
				if (file.getAbsolutePath().endsWith(".class")) {
					// 将class路径转换为全限定类名
					nameList.add(file.getAbsolutePath().replace("\\", "/").replace(rootPath, "").replace(".class", "")
							.replace("/", "."));
				}
			}
		}
	}

	/**
	 * 
	 * 根据注解和类对所有class分类
	 * 
	 * @throws Exception
	 */
	private static void sortClass() throws Exception {
		// 获取所有注解类并保存
		for (String className : nameList) {
			Class<?> clazz = Class.forName(className);
			if (clazz.isAnnotation()) {
				System.out.println("[AnnotationUtils] Scanning annotation: " + className);
				@SuppressWarnings("unchecked")
				Class<Annotation> annotation = (Class<Annotation>) clazz;
				annotationList.add(annotation);
			}
		}

		// 遍历所有类
		for (String className : nameList) {
			Class<?> clazz = Class.forName(className);
			// 跳过所有注解类
			if (clazz.isAnnotation()) {
				continue;
			}
			// 获取当前遍历类的所有属性
			Field[] fields = clazz.getFields();
			// 获取当前遍历类的所有方法
			Method[] methods = clazz.getMethods();
			// 遍历所有注解
			for (Class<Annotation> annotation : annotationList) {
				String annotationName = annotation.getName();
				// 当前遍历类拥有当前遍历注解,则根据注解和当前遍历类的类型进行分类保存
				if (null != clazz.getAnnotation(annotation)) {
					if (clazz.isInterface()) {
						System.out.println("[AnnotationUtils] Scanning class(interface): " + className);
						if (interfacePool.containsKey(annotationName)) {
							List<Class<?>> list = interfacePool.get(annotationName);
							list.add(clazz);
							interfacePool.put(annotationName, list);
						} else {
							List<Class<?>> list = new ArrayList<Class<?>>();
							list.add(clazz);
							interfacePool.put(annotationName, list);
						}
					} else if (clazz.isEnum()) {
						System.out.println("[AnnotationUtils] Scanning class(enum): " + className);
						if (enumPool.containsKey(annotationName)) {
							List<Class<?>> list = enumPool.get(annotationName);
							list.add(clazz);
							enumPool.put(annotationName, list);
						} else {
							List<Class<?>> list = new ArrayList<Class<?>>();
							list.add(clazz);
							enumPool.put(annotationName, list);
						}
					} else {
						System.out.println("[AnnotationUtils] Scanning class: " + className);
						if (classPool.containsKey(annotationName)) {
							List<Class<?>> list = classPool.get(annotationName);
							list.add(clazz);
							classPool.put(annotationName, list);
						} else {
							List<Class<?>> list = new ArrayList<Class<?>>();
							list.add(clazz);
							classPool.put(annotationName, list);
						}
					}
				}
				// 遍历当前遍历类的所有属性
				for (Field field : fields) {
					// 当前遍历属性拥有当前遍历注解,则根据注解和当前遍历属性的所属类进行分类保存
					if (null != field.getAnnotation(annotation)) {
						Map<String, List<Field>> map = null;
						List<Field> list = null;
						if (fieldPool.containsKey(annotationName)) {
							map = fieldPool.get(annotationName);
							if (map.containsKey(className)) {
								list = map.get(className);
							} else {
								list = new ArrayList<Field>();
							}
						} else {
							map = new HashMap<String, List<Field>>();
							list = new ArrayList<Field>();
						}
						list.add(field);
						map.put(className, list);
						fieldPool.put(annotationName, map);
					}
				}
				// 遍历当前遍历类的所有方法
				for (Method method : methods) {
					// 当前遍历属性拥有当前遍历注解,则根据注解和当前遍历属性的所属类进行分类保存
					if (null != method.getAnnotation(annotation)) {
						Map<String, List<Method>> map = null;
						List<Method> list = null;
						if (methodPool.containsKey(annotationName)) {
							map = methodPool.get(annotationName);
							if (map.containsKey(className)) {
								list = map.get(className);
							} else {
								list = new ArrayList<Method>();
							}
						} else {
							map = new HashMap<String, List<Method>>();
							list = new ArrayList<Method>();
						}
						list.add(method);
						map.put(className, list);
						methodPool.put(annotationName, map);
					}
				}
			}
		}
	}

	/**
	 * 
	 * 根据注解查询类
	 * 
	 * @param annotation
	 *            所查询的注解类
	 * @return 所有拥有所查询注解的类的ArrayList,如果未查询到结果或所传入类不是一个注解,则返回{@code null}
	 */

	public static List<Class<?>> getClasssByAnnotation(Class<?> annotation) {
		// 判断传入类是否为注解
		if (!annotation.isAnnotation()) {
			return null;
		}
		String annotationName = annotation.getName();
		List<Class<?>> result = null;
		if (classPool.containsKey(annotationName)) {
			result = classPool.get(annotationName);
		}
		return result;
	}

	/**
	 * 
	 * 根据注解查询接口
	 * 
	 * @param annotation
	 *            所查询的注解类
	 * @return 所有拥有所查询注解的接口的ArrayList,如果未查询到结果或所传入类不是一个注解,则返回{@code null}
	 */

	public static List<Class<?>> getInterfacesByAnnotation(Class<?> annotation) {
		// 判断传入类是否为注解
		if (!annotation.isAnnotation()) {
			return null;
		}
		String annotationName = annotation.getName();
		List<Class<?>> result = null;
		if (interfacePool.containsKey(annotationName)) {
			result = interfacePool.get(annotationName);
		}
		return result;
	}

	/**
	 * 
	 * 根据注解查询枚举类
	 * 
	 * @param annotation
	 *            所查询的注解类
	 * @return 所有拥有所查询注解的枚举类的ArrayList,如果未查询到结果或所传入类不是一个注解,则返回{@code null}
	 */

	public static List<Class<?>> getEnumsByAnnotation(Class<?> annotation) {
		// 判断传入类是否为注解
		if (!annotation.isAnnotation()) {
			return null;
		}
		String annotationName = annotation.getName();
		List<Class<?>> result = null;
		if (enumPool.containsKey(annotationName)) {
			result = enumPool.get(annotationName);
		}
		return result;
	}

	/**
	 * 
	 * 根据注解查询属性,并根据全限定类名分类
	 * 
	 * @param annotation
	 *            所查询的注解类
	 * @return 所有拥有所查询注解的属性的HashMap{全限定类名:
	 *         属性的ArrayList},如果未查询到结果或所传入类不是一个注解,则返回{@code null}
	 */

	public static Map<String, List<Field>> getFieldsByAnnotationSortByClass(Class<?> annotation) {
		// 判断传入类是否为注解
		if (!annotation.isAnnotation()) {
			return null;
		}
		String annotationName = annotation.getName();
		Map<String, List<Field>> result = null;
		if (fieldPool.containsKey(annotationName)) {
			result = fieldPool.get(annotationName);
		}
		return result;
	}

	/**
	 * 
	 * 根据注解查询方法,并根据全限定类名分类
	 * 
	 * @param annotation
	 *            所查询的注解类
	 * @return 所有拥有所查询注解的方法的HashMap{全限定类名:
	 *         方法的ArrayList},如果未查询到结果或所传入类不是一个注解,则返回{@code null}
	 */

	public static Map<String, List<Method>> getMethodsByAnnotationSortByClass(Class<?> annotation) {
		// 判断传入类是否为注解
		if (!annotation.isAnnotation()) {
			return null;
		}
		String annotationName = annotation.getName();
		Map<String, List<Method>> result = null;
		if (methodPool.containsKey(annotationName)) {
			result = methodPool.get(annotationName);
		}
		return result;
	}

	/**
	 * 
	 * 根据注解查询属性
	 * 
	 * @param annotation
	 *            所查询的注解类
	 * @return 所有拥有所查询注解的属性的ArrayList,如果未查询到结果或所传入类不是一个注解,则返回{@code null}
	 */
	public static List<Field> getFieldsByAnnotation(Class<?> annotation) {
		// 获取根据全限定类名分类的所有拥有所查询注解的属性的HashMap,如果未查询到结果,则返回null
		Map<String, List<Field>> temp = getFieldsByAnnotationSortByClass(annotation);
		if (null == temp) {
			return null;
		}
		// 将所有查询到的属性整合为一个ArrayList
		List<Field> result = new ArrayList<>();
		for (List<Field> list : temp.values()) {
			result.addAll(list);
		}
		return result;
	}

	/**
	 * 
	 * 根据注解查询方法
	 * 
	 * @param annotation
	 *            所查询的注解类
	 * @return 所有拥有所查询注解的方法的ArrayList,如果未查询到结果或所传入类不是一个注解,则返回{@code null}
	 */

	public static List<Method> getMethodsByAnnotation(Class<?> annotation) {
		// 获取根据全限定类名分类的所有拥有所查询注解的方法的HashMap,如果未查询到结果,则返回null
		Map<String, List<Method>> temp = getMethodsByAnnotationSortByClass(annotation);
		if (null == temp) {
			return null;
		}
		// 将所有查询到的方法整合为一个ArrayList
		List<Method> result = new ArrayList<>();
		for (List<Method> list : temp.values()) {
			result.addAll(list);
		}
		return result;
	}

	/**
	 * 
	 * 根据注解和类查询属性
	 * 
	 * @param annotation
	 *            所查询的注解类
	 * @param clazz
	 *            所查询的类
	 * @return 所有查询类下所有拥有所查询注解的属性的ArrayList,如果未查询到结果或所传入类不是一个注解,则返回{@code null}
	 */

	public static List<Field> getFieldByAnnotationAndClass(Class<?> annotation, Class<?> clazz) {
		// 判断传入类是否为注解
		if (!annotation.isAnnotation()) {
			return null;
		}
		String annotationName = annotation.getName();
		String className = clazz.getName();
		List<Field> result = null;
		if (fieldPool.containsKey(annotationName)) {
			Map<String, List<Field>> map = fieldPool.get(annotationName);
			if (map.containsKey(className)) {
				result = map.get(className);
			}
		}
		return result;
	}

	/**
	 * 
	 * 根据注解和类查询方法
	 * 
	 * @param annotation
	 *            所查询的注解类
	 * @param clazz
	 *            所查询的类
	 * @return 所有查询类下所有拥有所查询注解的方法的ArrayList,如果未查询到结果或所传入类不是一个注解,则返回{@code null}
	 */

	public static List<Method> getMethodByAnnotationAndClass(Class<?> annotation, Class<?> clazz) {
		// 判断传入类是否为注解
		if (!annotation.isAnnotation()) {
			return null;
		}
		String annotationName = annotation.getName();
		String className = clazz.getName();
		List<Method> result = null;
		if (methodPool.containsKey(annotationName)) {
			Map<String, List<Method>> map = methodPool.get(annotationName);
			if (map.containsKey(className)) {
				result = map.get(className);
			}
		}
		return result;
	}
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值