【问题标题】:How to scan classes for annotations?如何扫描类的注释?
【发布时间】:2012-10-19 04:13:43
【问题描述】:

我有一个普通的 jane servlets web 应用程序,我的一些类有以下注释:

@Controller
@RequestMapping(name = "/blog/")
public class TestController {
..

}

现在,当我的 servlet 应用程序启动时,我想获取所有具有 @Controller 注释的类的列表,然后获取 @RequestMapping 注释的值并将其插入字典中。

我该怎么做?

我也在使用 Guice 和 Guava,但不确定是否有任何与注释相关的助手。

【问题讨论】:

  • 为什么要直接访问注释?你打算和他们做点什么吗?您只是想要一个带有这些注释的类列表吗?
  • 我将获取 requestmapping 的值并将它们插入到字典中。

标签: java servlets guice guava


【解决方案1】:

您可以使用Reflections library,将您正在寻找的包和注释提供给它。

Reflections reflections = new Reflections("my.project.prefix");
Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(Controller.class);

for (Class<?> controller : annotated) {
    RequestMapping request = controller.getAnnotation(RequestMapping.class);
    String mapping = request.name();
}

当然,将所有 servlet 放在同一个包中会更容易一些。此外,您可能希望查找具有 RequestMapping 注释的类,因为这是您要从中获取值的类。

【讨论】:

  • 我可以指定包,这不是问题或限制。
【解决方案2】:

扫描注释非常困难。您实际上必须处理所有类路径位置并尝试查找与 Java 类 (*.class) 对应的文件。

我强烈建议使用提供此类功能的框架。例如,您可以查看Scannotation

【讨论】:

  • 很难???当你知道你的 CLASSPATH (你通常做的)时,我会说它是very simple。但我同意使用好工具是个好主意。
  • 想要高效完成,难度很大。特别是如果您不想为类路径上的所有类创建 Class 实例。
【解决方案3】:

如果你使用的是 Spring,

它有一个叫做AnnotatedTypeScanner 的类。
这个类内部使用了

ClassPathScanningCandidateComponentProvider

这个类具有实际扫描类路径资源的代码。它通过使用运行时可用的类元数据来做到这一点。

可以简单地扩展此类或使用相同的类进行扫描。下面是构造函数定义。

   /**
     * Creates a new {@link AnnotatedTypeScanner} for the given annotation types.
     * 
     * @param considerInterfaces whether to consider interfaces as well.
     * @param annotationTypes the annotations to scan for.
     */
    public AnnotatedTypeScanner(boolean considerInterfaces, Class<? extends Annotation>... annotationTypes) {

        this.annotationTypess = Arrays.asList(annotationTypes);
        this.considerInterfaces = considerInterfaces;
    }

【讨论】:

    【解决方案4】:

    试试corn-cps

    List<Class<?>> classes = CPScanner.scanClasses(new PackageNameFilter("net.sf.corn.cps.*"),new ClassFilter().appendAnnotation(Controller.class));
    for(Class<?> clazz: classes){
       if(clazz.isAnnotationPresent(RequestMapping.class){
         //This is what you want
       }
    }
    

    Maven 模块依赖:

    <dependency>
        <groupId>net.sf.corn</groupId>
        <artifactId>corn-cps</artifactId>
        <version>1.0.1</version>
    </dependency>
    

    访问网站https://sites.google.com/site/javacornproject/corn-cps了解更多信息

    【讨论】:

      【解决方案5】:

      以下代码对我有用,以下示例使用 Java 11 和 spring ClassPathScanningCandidateComponentProvider。用法是查找所有带有@XmlRootElement注解的类

      public static void main(String[] args) throws ClassNotFoundException {
          var scanner = new ClassPathScanningCandidateComponentProvider(false);
          scanner.addIncludeFilter(new AnnotationTypeFilter(XmlRootElement.class));
      
          //you can loop here, for multiple packages
          var beans = scanner.findCandidateComponents("com.example");
          for (var bean : beans) {
              var className = bean.getBeanClassName();
              Class clazz = Class.forName(className);
              //creates initial JAXBContext for later usage
              //JaxbContextMapper.get(clazz);
              System.out.println(clazz.getName());
          }
      }
      

      【讨论】:

        【解决方案6】:

        您可以使用 Google Guice 的 AOP 库,而不是直接使用反射。 AOP 是实现应用程序的横切关注点的常用方法,例如日志记录/跟踪、事务处理或权限检查。

        您可以在此处阅读更多信息:https://github.com/google/guice/wiki/AOP

        【讨论】:

          【解决方案7】:

          如果您可以访问您的 .class 文件,那么您可以使用以下类获取注释:

            RequestMapping reqMapping =  
                                   TestController.class.getAnnotation(RequestMapping.class);
            String name = reqMapping.name(); //now name shoud have value as "/blog/"
          

          另外请确保您的课程标有RetentionPolicyRUNTIME

            @Retention(RetentionPolicy.RUNTIME)
          

          【讨论】:

          • 问题是如何“获取所有具有@Controller 注释的类的列表”。检查注释的各个类是完全不同的事情。
          猜你喜欢
          • 1970-01-01
          • 2015-02-17
          • 2015-05-08
          • 2013-07-08
          • 1970-01-01
          • 1970-01-01
          • 2018-08-05
          • 2021-08-10
          相关资源
          最近更新 更多