>  기사  >  Java  >  지정된 패키지 아래의 모든 사용자 정의 주석을 가져옵니다.

지정된 패키지 아래의 모든 사용자 정의 주석을 가져옵니다.

巴扎黑
巴扎黑원래의
2017-06-23 15:26:302910검색

Reflections은 클래스 경로를 스캔하여 메타데이터를 색인화하여 런타임에 이러한 메타데이터를 쿼리할 수 있도록 하며 프로젝트의 여러 모듈에 대한 메타데이터 정보를 저장하고 수집할 수도 있습니다.

반사를 사용하여 지정된 패키지에서 사용자 정의된 Controller 및 RequestMapping 주석을 빠르게 스캔합니다. 먼저 @Controller로 주석이 달린 클래스를 스캔한 다음 이러한 클래스에서 @RequestMapping으로 주석이 달린 메서드를 얻은 다음 Java 반사 메서드를 호출합니다. RequestMapping을 사용하여 주석이 달린 정보를 출력합니다.

Maven 프로젝트 가져오기

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

Annotation 패키지에는 두 가지 맞춤 주석이 있습니다.

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 "";
}

RequestMapping 주석 메소드를 저장하는 객체는 모델 패키지

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;
    }
}

서비스 패키지 아래에 여러 클래스가 정의되어 있습니다. 사용자 정의 컨트롤러 주석을 사용하는 두 가지 클래스가 있습니다

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()");
    }
}

유틸리티 패키지는 사용자 정의를 얻기 위해 패키지를 스캔하는 아래 도구 클래스를 정의합니다. method

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;
    }

}

다음은 테스트 클래스입니다

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();
        }
    }
}

실행하고 가져옵니다.

지정된 패키지 아래의 모든 사용자 정의 주석을 가져옵니다.

Others

  1. Reflections를 사용하여 다음 메타데이터 정보를 쿼리합니다.

    반사 Google의 Guava 라이브러리와 Javassist 라이브러리를 사용합니다.

  • 특정 유형의 모든 하위 유형 가져오기

  • 특정 주석으로 표시된 모든 유형/멤버 변수 가져오기, 주석 매개변수 일치 지원.

  • 정규식을 사용하여 일치하는 모든 리소스 파일을 가져옵니다.

  • 메서드를 사용하여 모든 특정 서명(매개변수, 매개변수 주석, 반환 값 포함)을 가져옵니다.

  • 주석을 사용하여 클래스/메서드/멤버 변수 등을 장식합니다. 이후에는 이러한 주석이 저절로 적용되지 않으며 해당 주석의 개발자는 주석 정보를 추출하고 처리하기 위한 해당 도구를 제공해야 합니다(물론 주석 정의 시 @Retention(RetentionPolicy.RUNTIME) 수정이 사용되는 경우에만 해당됩니다. , JVM은 클래스 파일을 로드하고 클래스 파일에 저장된 주석은 런타임에 표시되므로 이를 구문 분석할 수 있습니다.

  • Java는 Annotation 인터페이스를 사용하여 프로그램 요소 앞에 주석을 나타냅니다. 이 인터페이스는 모든 주석을 위한 것입니다.

  • java5는 프로그램에서 주석을 허용할 수 있는 프로그램 요소를 나타내기 위해 java.lang.reflect 패키지 아래에 AnnotatedElement 인터페이스를 추가했습니다.

  • AnnotatedElement 인터페이스의 구현 클래스는 Class(클래스 요소), Field입니다. (클래스 멤버 변수 요소), 메소드(클래스 메소드 요소), 패키지(패키지 요소), 각 구현 클래스는 주석을 허용할 수 있는 프로그램 요소 유형을 나타냅니다.

  • 이런 방식으로 AnnotatedElement 인터페이스를 구현하는 Class, Method, Filed 및 기타 클래스의 인스턴스만 얻고 인스턴스 객체를 통해 클래스의 메서드를 호출하면 됩니다(AnnotatedElement 인터페이스의 추상 메서드 재정의) )을 얻으려면 이제 원하는 주석 정보가 있습니다.

  • Class 클래스의 인스턴스를 가져오는 세 가지 방법이 있습니다.

    • 객체를 사용하여 getClass() 메서드를 호출하여 클래스 인스턴스를 가져옵니다.

    • 클래스 인스턴스의 정적 forName() 메서드를 사용하세요. 클래스를 클래스화하고 클래스 이름을 사용하여 클래스 인스턴스를 얻습니다.

    • 다음과 같이 .class를 사용하여 클래스 인스턴스를 얻습니다. class name.class

  • AnnotatedElement 인터페이스에서 제공하는 추상 메서드(이러한 메서드는 이 인터페이스의 구현 클래스):

    • < ;T 확장 Annotation> T getAnnotation(Class< T> annotationClass)< T 확장 Annotation>은 A 유형이 주석일 수 있음을 나타내는 일반 매개변수 선언입니다. Annotation의 유형 또는 하위 클래스입니다.
      Function: 프로그램 요소에 존재하는 지정된 유형의 주석을 반환합니다. 이 유형의 주석이 없으면 null을 반환합니다.

    • Annotation[] getAnnotations()
      Function: 이 요소에 존재하는 모든 주석을 반환합니다. , 이 요소에 정의된 주석(상속됨)을 포함하여 표시되지 않습니다. (이 요소에 주석이 없으면 길이가 0인 배열이 반환됩니다.)

    • < T 확장 Annotation> T getDeclaredAnnotation(Class < 지정된 유형의 주석으로 프로그램 요소를 직접 수정합니다(상속된 주석 무시). 이 유형의 주석이 없으면 null을 반환합니다.

    • Annotation[] getDeclaredAnnotations()

      Function: 이 요소에 직접 존재하는 모든 주석을 반환합니다. 이 메서드는 상속된 주석을 무시합니다. (이 요소에 직접 주석이 없으면 길이가 0인 배열이 반환됩니다.)

    • boolean isAnnotationPresent(Class annotationClass)

      Function: 지정된 유형의 주석이 있는지 확인합니다. 프로그램 요소는 존재하면 true를 반환하고, 그렇지 않으면 false를 반환합니다.

    • <T extends Annotation> T[] getAnnotationsByTpye(Class annotationClass)
      Function: java8은 반복 주석 기능을 추가하므로 프로그램 요소를 수정하고 유형을 지정하는 여러 주석을 얻으려면 이 메서드를 사용해야 합니다.

    • T[] getDeclaredAnnotationsByTpye(ClassannotationClass)
      Function: java8에서는 반복되는 주석 기능을 추가하므로 프로그램 요소를 직접 수정하고 지정하는 여러 주석을 얻으려면 이 방법을 사용해야 합니다. 유형.

    Class는 getMethod(), getField() 및 getConstructor() 메서드(및 기타 메서드)를 제공합니다. 이러한 메서드는 각각 메서드, 필드 변수 및 생성자와 관련된 정보를 반환합니다. .

    위 내용은 지정된 패키지 아래의 모든 사용자 정의 주석을 가져옵니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명:
    본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.