How to run all methods with a given annotation?

大城市里の小女人 提交于 2020-01-12 04:04:06

问题


This is what I want to happen:

public class MainClass {
    public static void main(String args[]) { 
        run @mod(); // run all methods annotated with @mod annotation
    }
}

The annotation declaration:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface mod {
   String name() default "";
}

The methods to be called:

public class Good {
    @mod (name = "me1")
    public void calledcs(){
        System.out.println("called");
    }

    @mod (name = "me2")
    public void calledcs2(){
        System.out.println("called");
    }
}

or is there another way to achieve the same thing?


回答1:


You can do it using classpath scanning: Basically you go over every method of every class in the classpath and get all annotated with your given annotation. After that, you invoke the found methods.

Below is a runAllAnnotatedWith() method that would do it. It uses Reflections to do the dirty work of classpath scanning. For simplicity, it executes all found methods as if they were static and required no parameters.

public static void runAllAnnotatedWith(Class<? extends Annotation> annotation)
                                                               throws Exception {
    Reflections reflections = new Reflections(new ConfigurationBuilder()
                                  .setUrls(ClasspathHelper.forJavaClassPath())
                                  .setScanners(new MethodAnnotationsScanner()));
    Set<Method> methods = reflections.getMethodsAnnotatedWith(annotation);

    for (Method m : methods) {
        // for simplicity, invokes methods as static without parameters
        m.invoke(null); 
    }
}

You can run it using:

runAllAnnotatedWith(mod.class);

Note: It is possible to do it without using Reflections, but the code will get dirtier and dirtier.

Here's the full code (paste it all into a RunClass.java file):

import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.Set;

import org.reflections.Reflections;
import org.reflections.scanners.MethodAnnotationsScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;

public class RunClass {
    public static void main(String args[]) throws Exception {
        runAllAnnotatedWith(mod.class);
    }

    public static void runAllAnnotatedWith(Class<? extends Annotation> annotation) throws Exception {
        Reflections reflections = new Reflections(new ConfigurationBuilder()
                .setUrls(ClasspathHelper.forJavaClassPath()).setScanners(
                        new MethodAnnotationsScanner()));
        Set<Method> methods = reflections.getMethodsAnnotatedWith(annotation);

        for (Method m : methods) {
            m.invoke(null); // for simplicity, invoking static methods without parameters
        }
    }

    @mod(name = "me1")
    public static void calledcs() {
        System.out.println("called");
    }

    @mod(name = "me2")
    public static void calledcs2() {
        System.out.println("called2");
    }
}

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface mod {
    String name() default "";
}

To run it, you have to add the Reflections JAR to your project. Download it here.

If you use Maven, you can add it using:

<dependency>
    <groupId>org.reflections</groupId>
    <artifactId>reflections</artifactId>
    <version>0.9.9-RC1</version>
</dependency>



回答2:


Here's an example using an open source library I have published recently, called Reflect:

List<Method> methods = Reflect.on(someClass).methods().annotatedWith(mod.class);
for (Method m : methods) {
  m.invoke(null);
}

Maven Dependency:

<dependency>
    <groupId>org.pacesys</groupId>
    <artifactId>reflect</artifactId>
    <version>1.0.0</version>
</dependency>

More Recipes found at: https://github.com/gondor/reflect




回答3:


I think you can use reflection technique.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface mod {
   public String name() default "";
}

public class Fundamental {
   public static void main(String[] args) {
      // Get all methods in order.
      // runClass is the class you declare all methods with annotations.
      Method[] methods = runClass.getMethods();
      for(Method mt : methods) {
        if (mt.isAnnotationPresent(mod.class)) {
            // Invoke method with appropriate arguments
            Object obj = mt.invoke(runClass, null);
        }
      } 
   }
}


来源:https://stackoverflow.com/questions/16996033/how-to-run-all-methods-with-a-given-annotation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!