• 【反射】使用反射来获取注解原数据信息-类信息-方法信息等


    项目结构


    代码位置:https://github.com/ssslinppp/reflectdemo

    自定义注解

    ClassAnnotation.java

    @Documented
    @Target({ElementType.TYPE})
    @Retention(RUNTIME)
    public @interface ClassAnnotation {
        String classAlias() default "";
    }
    
    

    MethodAnnotation

    @Documented
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MethodAnnotation {
        String methodAlias() default "";
    }
    

    ParamAnnotation

    @Documented
    @Target({ElementType.PARAMETER})
    @Retention(RUNTIME)
    public @interface ParamAnnotation {
        String alias() default "";
    }
    

    接口实现自定义注解

    IDemoOne

    @ClassAnnotation(classAlias = "DemoInterfaceOne")
    public interface IDemoOne {
        @MethodAnnotation(methodAlias = "methodOne")
        public String getOne(@ParamAnnotation(alias = "keyAlias") String key);
    
        @MethodAnnotation(methodAlias = "methodMulti")
        public String getMulti(@ParamAnnotation(alias = "nameAlias") String name, @ParamAnnotation(alias = "ageAlias") int age);
    }
    

    IDemoTwo

    @ClassAnnotation(classAlias = "DemoInterfaceTwo")
    public interface IDemoTwo {
        @MethodAnnotation(methodAlias = "methodPostOne")
        public String postOne(@ParamAnnotation(alias = "mapAlias") HashMap map);
    }
    

    通过反射获取接口和注解信息

    获取接口信息-ClassAnnotation注解信息

        /**
         * 获取带有 ClassAnnotation 声明的所有接口和类,并获取 ClassAnnotation 声明中的原数据
         */
        public void getTypesAnnotatedWith() {
            // 获取带有 ClassAnnotation 声明的所有接口和类
            Set<Class<?>> requests = new Reflections("com.ssslinppp.*").getTypesAnnotatedWith(ClassAnnotation.class);
            for (Class<?> cls : requests) {
                System.out.println("- 接口或类全名:" + cls.getName());
                for (Annotation annotation : cls.getAnnotations()) {
                    System.out.println("-- 所有的接口信息 :" + annotation.annotationType());
                }
                System.out.println("-- 获取ClassAnnotation声明的classAlias:" + cls.getAnnotation(ClassAnnotation.class).classAlias());
                System.out.println();
            }
        }
    

    输出:

    ########## 获取所有 ClassAnnotation 声明的类和接口  start ####### 
    - 接口或类全名:com.ssslinppp.reflectdemo.interfaces.IDemoOne
    -- 所有的接口信息 :interface com.ssslinppp.reflectdemo.annotations.ClassAnnotation
    -- 获取ClassAnnotation声明的classAlias:DemoInterfaceOne
    
    - 接口或类全名:com.ssslinppp.reflectdemo.interfaces.IDemoTwo
    -- 所有的接口信息 :interface com.ssslinppp.reflectdemo.annotations.ClassAnnotation
    -- 获取ClassAnnotation声明的classAlias:DemoInterfaceTwo
    
    ###### 获取所有 ClassAnnotation 声明的类和接口  end ###### 
    

    获取方法信息-MethodAnnotation注解信息-ParamAnnotation注解信息

        public void getMethodInfo() {
            // 获取带有 ClassAnnotation 声明的所有接口和类
            Set<Class<?>> requests = new Reflections("com.ssslinppp.*").getTypesAnnotatedWith(ClassAnnotation.class);
            for (Class<?> cls : requests) {
                System.out.println("类或接口名:" + cls.getSimpleName());
                for (Method method : cls.getMethods()) {
                    System.out.println("   方法名:" + method.getName() + ", 返回值类型:" + method.getReturnType());
    
                    // 获取方法Annotation
                    MethodAnnotation methodAnnotation = method.getAnnotation(MethodAnnotation.class);
                    System.out.println("   方法Annotation原数据,methodAlias:" + methodAnnotation.methodAlias());
    
                    // 获取参数
                    for (Parameter parameter : method.getParameters()) {
                        System.out.println("    参数别名:" + parameter.getAnnotation(ParamAnnotation.class).alias());
                    }
                    System.out.println();
                }
            }
        }
    

    输出:

    @@@@ 获取 方法信息  start @@@@ 
    类或接口名:IDemoOne
       方法名:getOne, 返回值类型:class java.lang.String
       方法Annotation原数据,methodAlias:methodOne
        参数别名:keyAlias
    
       方法名:getMulti, 返回值类型:class java.lang.String
       方法Annotation原数据,methodAlias:methodMulti
        参数别名:nameAlias
        参数别名:ageAlias
    
    类或接口名:IDemoTwo
       方法名:postOne, 返回值类型:class java.lang.String
       方法Annotation原数据,methodAlias:methodPostOne
        参数别名:mapAlias
    
    @@@@ 获取 方法信息  end @@@@ 
    

    完整测试代码

    引用反射工具类

    <dependency>
                <groupId>org.reflections</groupId>
                <artifactId>reflections</artifactId>
                <version>0.9.10</version>
            </dependency>
    

    ReflectDemo

    package com.ssslinppp.reflectdemo.reflect;
    
    import com.ssslinppp.reflectdemo.annotations.ClassAnnotation;
    import com.ssslinppp.reflectdemo.annotations.MethodAnnotation;
    import com.ssslinppp.reflectdemo.annotations.ParamAnnotation;
    import org.reflections.Reflections;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.stereotype.Component;
    
    import java.lang.annotation.Annotation;
    import java.lang.reflect.Method;
    import java.lang.reflect.Parameter;
    import java.util.Set;
    
    @Component
    public class ReflectDemo implements CommandLineRunner {
        /**
         * 获取带有 ClassAnnotation 声明的所有接口和类,并获取 ClassAnnotation 声明中的原数据
         */
        public void getTypesAnnotatedWith() {
            // 获取带有 ClassAnnotation 声明的所有接口和类
            Set<Class<?>> requests = new Reflections("com.ssslinppp.*").getTypesAnnotatedWith(ClassAnnotation.class);
            for (Class<?> cls : requests) {
                System.out.println("接口或类全名:" + cls.getName());
                for (Annotation annotation : cls.getAnnotations()) {
                    System.out.println("  所有的接口信息 :" + annotation.annotationType());
                }
                System.out.println("   获取ClassAnnotation声明的classAlias:" + cls.getAnnotation(ClassAnnotation.class).classAlias());
                System.out.println();
            }
        }
    
        public void getMethodInfo() {
            // 获取带有 ClassAnnotation 声明的所有接口和类
            Set<Class<?>> requests = new Reflections("com.ssslinppp.*").getTypesAnnotatedWith(ClassAnnotation.class);
            for (Class<?> cls : requests) {
                System.out.println("类或接口名:" + cls.getSimpleName());
                for (Method method : cls.getMethods()) {
                    System.out.println("   方法名:" + method.getName() + ", 返回值类型:" + method.getReturnType());
    
                    // 获取方法Annotation
                    MethodAnnotation methodAnnotation = method.getAnnotation(MethodAnnotation.class);
                    System.out.println("   方法Annotation原数据,methodAlias:" + methodAnnotation.methodAlias());
    
                    // 获取参数
                    for (Parameter parameter : method.getParameters()) {
                        System.out.println("    参数别名:" + parameter.getAnnotation(ParamAnnotation.class).alias());
                    }
                    System.out.println();
                }
            }
        }
    
        @Override
        public void run(String... strings) throws Exception {
            System.out.println("@@@@ 获取所有 ClassAnnotation 声明的类和接口  start @@@@ ");
            getTypesAnnotatedWith();
            System.out.println("@@@@ 获取所有 ClassAnnotation 声明的类和接口  end @@@@ ");
            System.out.println();
    
            System.out.println("@@@@ 获取 方法信息  start @@@@ ");
            getMethodInfo();
            System.out.println("@@@@ 获取 方法信息  end @@@@ ");
        }
    }
    
    
  • 相关阅读:
    本地及远程二级缓存
    ubuntu下使用golang、qml与ubuntu sdk开发桌面应用
    TCP之心跳包实现思路
    Java读书笔记1
    回文字符串
    6.1 遍历字符串
    linux系统文件夹的作用 good
    在线程中建立Form遇到的问题
    QTabWidget and QTabBar.的文字的颜色设置,三种方法
    Ring3下Hook NtQueryDirectoryFile隐藏文件
  • 原文地址:https://www.cnblogs.com/ssslinppp/p/7573963.html
Copyright © 2020-2023  润新知