24

我知道有一组令人难以置信的工具可以在 java 中加载插件类,但今天我想到了一个想法。

如果我在包“org.home.junk”中有一堆带注释和未注释的类(使用注释“@AnnotatedClass”进行注释)并且这些类具有带有注释“@AnnotatedMethod”的注释方法。

第一个问题:我能否在运行时获取该特定包中所有类的数组/集合,以便我可以检查哪些类被注释并创建它们的实例。(但是我知道如何检查 Some.class 是否有本指南提供的注释:http: //isagoksu.com/2009/development/java/creating-custom-annotations-and-making-use-of-them/

第二个问题: - 如果我可以在第一个问题中做我想做的事 - 这样做最政治化的方式是什么?

我相信这是可能的,因为我了解 JUnit 以某种类似的方式加载测试用例类。

如果这可以用最少的第三方库等来完成,那也会很酷 - 如果可能的话:)

4

4 回答 4

30

第一个答案:看看这个项目

Reflections reflections = new Reflections("org.home.junk");
Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(javax.persistence.Entity.class);

它返回org.home.junk带有javax.persistence.Entity注释的所有类。

第二个答案:要创建上述类的新实例,您可以这样做

for (Class<?> clazz : annotated) {
    final Object newInstance = clazz.newInstance();
}

希望这能回答一切。

于 2012-08-18T20:23:05.027 回答
2

如果您有 Spring(第 3 方,抱歉 :-)),请使用org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider

可以在这个 SO question中找到代码使用示例

于 2012-08-18T19:31:37.320 回答
2

它可以通过检查文件系统的技术来完成,因为它更多的是类加载器问题而不是反射问题。检查一下:你能使用反射找到包中的所有类吗?.

如果可以查看某个目录下存在的所有类文件,使用该方法就可以很方便的获取到对应的类

Class<?> klass = Class.forName(className)

知道一个类是否被注释是一个反射问题。获取类中使用的注解是这样完成的:

Annotation[] annotations = klass.getAnnotations();

请务必使用在运行时可见的保留策略类型定义您的自定义注释。

@Retention(RetentionPolicy.RUNTIME) 

这篇文章是获取更多信息的好资源:http: //tutorials.jenkov.com/java-reflection/annotations.html

于 2012-08-18T20:50:14.700 回答
1

这完全取决于您对注释的要求。

比如@EJB:这个注解的设计是为了让容器识别和执行 EJB 特定的工作,这需要扫描文件然后找到这样的类。

但是,如果您的要求只是启用基于注释的特定功能,那么您可以仅使用 java 反射来实现

例如@NotNull:此注释是在 JSR 303 中设计的,用于验证 Annotated 元素不为空。此功能可以在运行时使用反射 API 轻松实现

于 2012-08-18T20:02:00.113 回答