21

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

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

}

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

我怎样才能做到这一点?

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

4

7 回答 7

41

您可以通过向其提供您正在寻找的包和注释来使用Reflections 库。

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注释的类,因为这是您要从中获取值的类。

于 2012-10-29T20:10:07.723 回答
5

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

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

于 2012-10-29T19:55:06.833 回答
5

如果您使用的是 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;
    }
于 2019-05-28T10:01:34.697 回答
2

试试玉米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了解更多信息

于 2013-05-19T21:41:13.127 回答
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());
    }
}
于 2020-09-18T04:25:51.587 回答
-1

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

你可以在这里阅读更多关于它的信息:https ://github.com/google/guice/wiki/AOP

于 2019-06-13T15:19:43.480 回答
-3

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

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

另请确保,您的课程标记RetentionPolicyRUNTIME

  @Retention(RetentionPolicy.RUNTIME)
于 2012-10-29T20:04:51.823 回答