Home >Java >javaTutorial >Get all custom annotations under the specified package

Get all custom annotations under the specified package

巴扎黑
巴扎黑Original
2017-06-23 15:26:303017browse

Reflections index metadata by scanning the classpath, allowing these metadata to be queried at runtime, and can also save and collect metadata information for multiple modules in the project.

Use Reflections to quickly scan the customized Controller and RequestMapping annotations under the specified package. First scan the classes annotated with @Controller, then obtain the methods annotated with @RequestMapping under these classes, and then use Java The reflection invoke method calls the method annotated with RequestMapping and outputs the information on the annotation.

Maven project import

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

There are two annotations customized under the annotation package.

Controller.java:

package annotationTest.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)// 注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Retention(RetentionPolicy.RUNTIME)//定义注解的作用目标**作用范围字段、枚举的常量/方法
@Documented//说明该注解将被包含在javadoc中
public @interface Controller {
    String value() default "";
}

RequestMapping.java

package annotationTest.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestMapping {
    String value() default "";

    /**
     * 是否为序列号
     *
     * @return
     */
    boolean id() default false;

    /**
     * 字段名称
     *
     * @return
     */
    String name() default "";

    /**
     * 字段描述
     *
     * @return
     */
    String description() default "";
}

An object storing the RequestMapping annotation method is defined under the model package

ExecutorBean.java

package annotationTest.model;

import java.lang.reflect.Method;

public class ExecutorBean {
    private Object object;

    private Method method;

    public Object getObject() {
        return object;
    }

    public void setObject(Object object) {
        this.object = object;
    }

    public Method getMethod() {
        return method;
    }

    public void setMethod(Method method) {
        this.method = method;
    }
}

The service package defines several classes, two of which use custom Controller annotations

SunService. java

package annotationTest.service;

import annotationTest.annotation.Controller;
import annotationTest.annotation.RequestMapping;

@Controller
public class SunService {
    @RequestMapping(id = true, name = "test1", description = "sun测试1", value = "/test1")
    public void test1() {
        System.out.println("SunService->test1()");
    }

    @RequestMapping(id = true, name = "test2", description = "sun测试2", value = "/test2")
    public void test2() {
        System.out.println("SunService->test2()");
    }
}

MoonService.java

package annotationTest.service;

import annotationTest.annotation.Controller;
import annotationTest.annotation.RequestMapping;

@Controller
public class MoonService {
    @RequestMapping(id = true, name = "moon测试3", description = "/test3", value = "/test3")
    public void test3() {
        System.out.println("MoonService->test3()");
    }

    @RequestMapping(id = true, name = "moon测试4", description = "/test4", value = "/test4")
    public void test4() {
        System.out.println("MoonService->test4()");
    }
}

Stars.java

package annotationTest.service;

import annotationTest.annotation.RequestMapping;

public class Stars {
    @RequestMapping(id = true, name = "test1", description = "stars测试1", value = "/test1")
    public void test1() {
        System.out.println("Stars->test1()");
    }
}

The util package defines a tool class to scan the package to obtain custom annotations. Classes and methods

AnnoManageUtil.java

package annotationTest.util;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import annotationTest.annotation.Controller;
import annotationTest.annotation.RequestMapping;
import annotationTest.model.ExecutorBean;
import org.reflections.Reflections;

public final class AnnoManageUtil {

    /**
     * 获取指定文件下面的RequestMapping方法保存在mapp中
     *
     * @param packageName
     * @return
     */
    public static Map<String, ExecutorBean> getRequestMappingMethod(String packageName) {
        Reflections reflections = new Reflections(packageName);
        Set<Class<?>> classesList = reflections.getTypesAnnotatedWith(Controller.class);

        // 存放url和ExecutorBean的对应关系
        Map<String, ExecutorBean> mapp = new HashMap<String, ExecutorBean>();
        for (Class classes : classesList) {
            //得到该类下面的所有方法
            Method[] methods = classes.getDeclaredMethods();

            for (Method method : methods) {
                //得到该类下面的RequestMapping注解
                RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
                if (null != requestMapping) {
                    ExecutorBean executorBean = new ExecutorBean();
                    try {
                        executorBean.setObject(classes.newInstance());
                    } catch (InstantiationException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                    executorBean.setMethod(method);
                    mapp.put(requestMapping.value(), executorBean);

                }
            }
        }
        return mapp;
    }

}

The following test package is a test class

package annotationTest.test;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import annotationTest.annotation.Controller;
import annotationTest.annotation.RequestMapping;
import annotationTest.model.ExecutorBean;
import annotationTest.util.AnnoManageUtil;

public class Test {
    public static void main(String[] args) {
        List<Class<?>> classesList = null;
        classesList = AnnoManageUtil.getPackageController("annotationTest.service", Controller.class);
        Map<String, ExecutorBean> mmap = new HashMap<String, ExecutorBean>();
        AnnoManageUtil.getRequestMappingMethod(classesList, mmap);
        ExecutorBean bean = mmap.get("/test1");

        try {
            bean.getMethod().invoke(bean.getObject());
            RequestMapping annotation = bean.getMethod().getAnnotation(RequestMapping.class);
            System.out.println("注解名称:" + annotation.name() + "\t注解描述:" + annotation.description());
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

Run and get:

Get all custom annotations under the specified package

Others

  1. Using Reflections, you can query the following metadata information:

    Reflections relies on Google’s Guava library and Javassist library.

  • Get all subtypes of a certain type

  • Get all types/member variables marked with a certain annotation, support annotations Parameters match.

  • Use regular expressions to get all matching resource files

  • Method to get all specific signatures (including parameters, parameter annotations, return values)

  • After using annotations to modify classes/methods/member variables, etc., these annotations will not take effect by themselves. The developers of these annotations must provide corresponding tools to extract and process them. Annotation information (of course, only when the @Retention(RetentionPolicy.RUNTIME) modification is used when defining the annotation, the JVM will extract the annotations saved in the class file when loading the class file, and the annotation will be visible at runtime, so that we can Able to parse).

  • Java uses the Annotation interface to represent the annotations in front of program elements. This interface is the parent interface of all annotations.

  • java5 has added the AnnotatedElement interface under the java.lang.reflect package to represent program elements that can accept annotations in the program.

  • AnnotatedElement The implementation classes of the interface are: Class (class element), Field (member variable element of the class), Method (method element of the class), and Package (package element). Each implementation class represents a program element type that can accept annotations.

  • In this way, we only need to obtain instances of Class, Method, Filed and other classes that implement the AnnotatedElement interface, and call the methods in the class through the instance object (abstract in the AnnotatedElement interface method), we can get the annotation information we want.

  • There are three ways to obtain an instance of the Class class:

    • Use the object to call the getClass() method to obtain a Class instance

    • Use the static forName() method of the Class class to obtain the Class instance using the class name

    • ##Use the .class method to obtain the Class instance, such as: class name .class

  • Abstract methods provided by the AnnotatedElement interface (these methods are overridden in the implementation class of this interface):

    • T getAnnotation(Class< T> annotationClass)< T extends Annotation> is a generic parameter declaration, indicating that the type of A can only be the Annotation type or a subclass of Annotation.

      Function: Return the annotations of the specified type that exist on the program element. If the annotation of this type does not exist, return null

    • Annotation[] getAnnotations()

      Function: Returns all annotations that exist on this element, including annotations that are not explicitly defined on this element (inherited). (If this element has no annotation, a zero-length array is returned.)

    • < T extends Annotation> T getDeclaredAnnotation(Class < T> annotationClass)

      Function: This It is a new method in Java 8. This method returns annotations that directly modify the program element and specify the type (ignoring inherited annotations). If annotations of this type do not exist, return null.

    • Annotation[] getDeclaredAnnotations()

      Function: Return all annotations that exist directly on this element, this method will ignore inheritance annotation. (If no annotation exists directly on this element, an array with a length of zero is returned.)

    • boolean isAnnotationPresent(Class annotationClass)

      Function: Judgment Whether there is an annotation of the specified type on the program element. If it exists, it returns true, otherwise it returns false.

    • <T extends Annotation> T[] getAnnotationsByTpye(Class annotationClass)
      Function: Because java8 adds a repeated annotation function, you need to use this method to obtain the modified program element and the specified type. multiple annotations.

    • ## T[] getDeclaredAnnotationsByTpye(ClassannotationClass)

      Function: Because java8 has added the repeated annotation function, you need to use this method to obtain direct modification This program element, multiple annotations of the specified type.

    Class provides getMethod(), getField() and getConstructor() methods (and other methods), which are related to methods, domain variables and constructors respectively. Information, these methods return objects of type Method, Field and Constructor.

    The above is the detailed content of Get all custom annotations under the specified package. For more information, please follow other related articles on the PHP Chinese website!

    Statement:
    The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn