如何扫描类注释?

时间:2012-10-29 19:48:16

标签: java servlets guice guava

我有一个简单的jane servlets Web应用程序,我的一些类有以下注释:

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

}

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

我该怎么做?

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

7 个答案:

答案 0 :(得分:35)

您可以使用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注释的类,因为这是您希望从中获取值的类。

答案 1 :(得分:4)

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

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

答案 2 :(得分:2)

尝试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以获取更多信息

答案 3 :(得分:0)

如果您使用的是Spring,

它有一个称为AnnotatedTypeScanner的类。
此类内部使用

ClassPathScanningCandidateComponentProvider

此类具有用于实际扫描 classpath 资源的代码。它通过使用运行时可用的类元数据来实现此目的。

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

   /**
     * 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 :(得分:0)

以下代码为我工作,以下示例使用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());
    }
}

答案 5 :(得分:-1)

您可以直接使用Google Guice的AOP库,而不是直接使用反射,从而可以轻松得多。 AOP是一种实现应用程序跨领域关注点的常用方法,例如日志记录/跟踪,事务处理或权限检查。

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

答案 6 :(得分:-3)

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

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

另外请确保您的课程标有RetentionPolicy RUNTIME

  @Retention(RetentionPolicy.RUNTIME)