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
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을 반환합니다.
Function: 이 요소에 직접 존재하는 모든 주석을 반환합니다. 이 메서드는 상속된 주석을 무시합니다. (이 요소에 직접 주석이 없으면 길이가 0인 배열이 반환됩니다.)
Function: 지정된 유형의 주석이 있는지 확인합니다. 프로그램 요소는 존재하면 true를 반환하고, 그렇지 않으면 false를 반환합니다.
<T extends Annotation> T[] getAnnotationsByTpye(Class
Function: java8은 반복 주석 기능을 추가하므로 프로그램 요소를 수정하고 유형을 지정하는 여러 주석을 얻으려면 이 메서드를 사용해야 합니다.
Function: java8에서는 반복되는 주석 기능을 추가하므로 프로그램 요소를 직접 수정하고 지정하는 여러 주석을 얻으려면 이 방법을 사용해야 합니다. 유형.
Class는 getMethod(), getField() 및 getConstructor() 메서드(및 기타 메서드)를 제공합니다. 이러한 메서드는 각각 메서드, 필드 변수 및 생성자와 관련된 정보를 반환합니다. .
위 내용은 지정된 패키지 아래의 모든 사용자 정의 주석을 가져옵니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!