nullpointer nullpointer - 2 months ago 12
Java Question

How to use reflection to identify annotated methods?

We are trying to use reflection to extract the exact mapped values to our methods. The code structure in the target module consists of multiple classes as follows -

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

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

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


What we are trying to grep here is the list of endpoints like
for which the code we tried to execute filters all such classes based on the
annotation and at the same time we are able to get the list of all the endpoints separately. The code we have tried so far is -

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 -> filteredClasses.add(beanDefinition.getBeanClassName()));

// call to get the annotation details -> 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"
} catch (ClassNotFoundException e) {

// 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); -> {
if (m != null) {
RequestMapping mappedValue = m.getAnnotation(RequestMapping.class); //this is listing out all the @RequestMapping annotations like "/questions" , "/ask" etc.

But the missing part is the concatenation of the class to method RequestMapping value here.

How do we loop inside a class to search annotations only from its methods?

Or is there any simpler way of doing this from what we are using?

References used - Scanning Java annotations at runtime && How to run all methods with a given annotation?


Aren't endpoints methods in the end?

So, I think what you need to implement is:

  1. => Retrieve all declared methods of each and any class that has @RequestMapping and @Controller annotations.

  2. => Iterate the annotations on each of those Method objects to check if they contain @RequestMapping


  1. => Iterate through all the Methods for each class in Step 1 and find the annotated one's using method.getDeclaredAnnotation(RequestMapping.class) and skip Step 3

  2. => Remember that combination of class and method for your mapping

  3. => Do some error handling, in case you don't find any annotated method in there.