我有一个注释@MyAnnotation
,我可以使用它注释任何类型(类)。然后我有一个名为AnnotatedClassRegister
的类,我希望它注册所有用@MyAnnotation
注释的类,以便我以后可以访问它们。如果可能的话,我想在创建AnnotatedClassRegister
时自动注册这些类,最重要的是在注释类被实例化之前。
我有AspectJ和Guice供我使用。到目前为止,我提出的唯一解决方案是使用Guice将AnnotatedClassRegister
的单个实例注入到一个方面,该方面搜索所有使用@MyAnnotation
注释的类,并添加注册此类所需的代码它的构造函数中的类。这个解决方案的缺点是我需要实例化每个带注释的类,以便实际运行AOP添加的代码,因此我无法利用这些类的延迟实例化。
我的解决方案的简化伪代码示例:
// This is the class where annotated types are registered
public class AnnotatedClassRegister {
public void registerClass(Class<?> clz) {
...
}
}
// This is the aspect which adds registration code to constructors of annotated
// classes
public aspect AutomaticRegistrationAspect {
@Inject
AnnotatedClassRegister register;
pointcutWhichPicksConstructorsOfAnnotatedClasses(Object annotatedType) :
execution(/* Pointcut definition */) && args(this)
after(Object annotatedType) :
pointcutWhichPicksConstructorsOfAnnotatedClasses(annotatedType) {
// registering the class of object whose constructor was picked
// by the pointcut
register.registerClass(annotatedType.getClass())
}
}
我应该采用什么方法来解决这个问题?有没有简单的方法通过反射在classpath中获取所有这些带注释的类,所以我根本不需要使用AOP?还是其他任何解决方案?
非常感谢任何想法,谢谢!
答案 0 :(得分:7)
有可能:
获取类路径中的所有路径。解析System.getProperties().getProperty("java.class.path", null)
以获取所有路径。
使用ClassLoader.getResources(path)
获取所有资源并检查课程:http://snippets.dzone.com/posts/show/4831
答案 1 :(得分:4)
可靠性并不简单,但我会以纯Java方式进行:
.class
结尾的每个条目,Class.forName()
以获取Class对象方面不会帮助你,因为方面只适用于实际执行的代码。
但annotation processing可能是一个选项,创建一个处理器来记录所有带注释的类,并创建一个提供这些类的列表的类
答案 2 :(得分:0)
好吧,如果你的AnnotatedClassRegister.registerClass()
不必在AnnotatedClassRegister
创建时立即调用,但它可能要等到第一个实例化的类,那么我会考虑使用Guice {{1注册一个TypeListener
,检查一个类是否注释了Matcher
。
这样,您不需要搜索所有这些类,它们将在使用之前注册。请注意,这仅适用于由Guice实例化的类。
答案 3 :(得分:0)
我会在AspectJ中使用staticinitialization()
切入点,并在加载时将类修改到寄存器中,如下所示:
after() : staticinitialization(@MyAnnotation *) {
register.registerClass(thisJoinPointStaticPart.getSignature().getDeclaringType());
}
一块蛋糕,非常简单而优雅。
答案 4 :(得分:0)
您可以像这样使用 ClassGraph
包:
Java:
try (ScanResult scanResult = new ClassGraph().enableAnnotationInfo().scan()) {
for (ClassInfo classInfo = scanResult.getClassesWithAnnotation(classOf[MyAnnotation].getName()) {
System.out.println(String.format("classInfo = %s", classInfo.getName()));
}
}
斯卡拉:
Using(new ClassGraph().enableAnnotationInfo.scan) { scanResult =>
for (classInfo <- scanResult.getClassesWithAnnotation(classOf[MyAnnotation].getName).asScala) {
println(s"classInfo = ${classInfo.getName}")
}
}