我们正在尝试使用反射来提取映射到我们的方法的确切值。目标模块中的代码结构由以下多个类组成-
@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值的连接。
如何在类内部循环,只从类的方法中搜索注释?
或者有什么更简单的方法从我们正在使用的?
使用的引用-在运行时扫描Java注释&&如何运行所有的方法与给定的注释?
端点方法在结束?
所以,我认为你需要实现的是:
-
=>检索具有
@RequestMapping
和@Controller
注释的每个类的所有声明方法。 -
=>迭代每个Method对象上的注释以检查它们是否包含
@RequestMapping
或
-
=>遍历步骤1中每个类的所有
Method
s,找到使用method.getDeclaredAnnotation(RequestMapping.class)
的注释者并跳过步骤3 -
=>记住类和方法的组合用于映射
-
=>做一些错误处理,如果你没有找到任何注释方法