如何使用反射来识别带注释的方法?

时间:2016-09-07 04:15:36

标签: java reflection annotations

我们正在尝试使用反射将精确的映射值提取到我们的方法中。目标模块中的代码结构由多个类组成,如下所示 -

@Controller
@RequestMapping(value = "/questions")
public class XYZController {

  @RequestMapping(value = "/ask")
  public boolean myMethod1() {..}

  @RequestMapping(value = "/{questionNo.}/{questionTitle}")
  public MyReturnObject myMethod2(){..}

}

我们在这里尝试grep的是端点列表,例如/questions/ask/questions/{questionNo.}/{questionTitle},我们尝试执行的代码根据@Controller注释过滤所有这些类,并且同时我们能够分别获得所有端点的列表。我们到目前为止尝试的代码是 -

public class ReflectApi {

    public static void main(String[] args) {
        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(true);
        final List<String> filteredClasses = new ArrayList<>();
        scanner.addIncludeFilter(new AnnotationTypeFilter(Controller.class));
        Set<BeanDefinition> filteredPackage = scanner.findCandidateComponents("com.package.test");

        // gives me a list of all the filtered classes
        filteredPackage.stream().forEach(beanDefinition -> filteredClasses.add(beanDefinition.getBeanClassName()));

        // call to get the annotation details
        filteredClasses.stream().forEach(filteredClass -> getEndPoints(filteredClass));
    }

    public static void getEndPoints(String controllerClassName) {
        try {
            Class clazz = Class.forName(controllerClassName);
            Annotation classAnnotation = clazz.getDeclaredAnnotation(RequestMapping.class);
            if (classAnnotation != null) {
                RequestMapping mappedValue = (RequestMapping) clazz.getAnnotation(RequestMapping.class);
                System.out.println("Controller Mapped -> " + mappedValue.value()[0]); //This gives me the value for class like "/questions"
                runAllAnnotatedWith(RequestMapping.class);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    // followed from a SO reference
    public static void runAllAnnotatedWith(Class<? extends Annotation> annotation) {
        Reflections reflections = new Reflections(new ConfigurationBuilder().setUrls(ClasspathHelper.forJavaClassPath())
                .setScanners(new MethodAnnotationsScanner()));
        Set<Method> methods = reflections.getMethodsAnnotatedWith(annotation);

        methods.stream().forEach(m -> {
            if (m != null) {
                RequestMapping mappedValue = m.getAnnotation(RequestMapping.class); //this is listing out all the @RequestMapping annotations like "/questions" , "/ask" etc.
                    System.out.println(mappedValue.value()[0]);
            }
        });
    }
}

但缺少的部分是此类与方法RequestMapping值的串联。

我们如何在类中循环以仅从其方法中搜索注释?

或者有什么比我们使用的更简单的方法吗?

使用的参考文献 - Scanning Java annotations at runtime&amp;&amp; How to run all methods with a given annotation?

1 个答案:

答案 0 :(得分:2)

Aren的端点方法到底是什么?

所以,我认为你需要实现的是:

  1. =&GT;检索每个以及具有@RequestMapping@Controller注释的所有类的 declared methods

  2. =&GT;对每个 Method 对象上的注释进行迭代,以检查它们是否包含@RequestMapping

    1. =&GT;在第1步中为每个类迭代所有Method并使用method.getDeclaredAnnotation(RequestMapping.class)找到带注释的一个并跳过第3步 < / p>

    2. =&GT;请记住,您的映射方法的组合

    3. =&GT;如果您在那里找不到任何带注释的方法,请进行一些错误处理。