java 如何使用给定的注释运行所有方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16996033/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-01 00:38:44  来源:igfitidea点击:

How to run all methods with a given annotation?

javareflectionannotations

提问by MSPO

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 annotationdeclaration:

注解声明:

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

The methodsto 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?

还是有另一种方法可以实现同样的目标?

回答by acdcjunior

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 Reflectionsto do the dirty work of classpath scanning. For simplicity, it executes all found methods as if they were staticand required no parameters.

下面是一个runAllAnnotatedWith()可以做到这一点的方法。它使用反射来完成类路径扫描的肮脏工作。为简单起见,它执行所有找到的方法,就好像它们static不需要参数一样。

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.

注意:不使用Reflections也可以做到这一点,但是代码会越来越脏。

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

这是完整的代码(将其全部粘贴到 RunClass.java 文件中):

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 ReflectionsJAR to your project. Download it here.

要运行它,您必须将ReflectionsJAR添加到您的项目中。在这里下载

If you use Maven, you can add it using:

如果您使用 Maven,则可以使用以下命令添加它:

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

回答by Jeremy Unruh

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

这是一个使用我最近发布的名为 Reflect 的开源库的示例:

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

Maven Dependency:

Maven 依赖:

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

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

更多食谱见:https: //github.com/gondor/reflect

回答by cat_minhv0

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);
        }
      } 
   }
}