Java 如何扫描类中的注释?
我有一个简单的jane servlets web应用程序,我的一些类有以下注释:Java 如何扫描类中的注释?,java,servlets,guice,guava,Java,Servlets,Guice,Guava,我有一个简单的jane servlets web应用程序,我的一些类有以下注释: @Controller @RequestMapping(name = "/blog/") public class TestController { .. } 现在,当我的servlet应用程序启动时,我希望获得具有@Controller注释的所有类的列表,然后获取@RequestMapping注释的值并将其插入字典中 我该怎么做 我也在使用Guice和Guava,但不确定是否有注释相关的帮助工具。扫描注释非常
@Controller
@RequestMapping(name = "/blog/")
public class TestController {
..
}
现在,当我的servlet应用程序启动时,我希望获得具有@Controller注释的所有类的列表,然后获取@RequestMapping注释的值并将其插入字典中
我该怎么做
我也在使用Guice和Guava,但不确定是否有注释相关的帮助工具。扫描注释非常困难。实际上,您必须处理所有类路径位置,并尝试查找与Java类(*.class)对应的文件
我强烈建议使用提供此类功能的框架。例如,您可以查看。如果您可以访问.class文件,则可以使用以下类获取注释:
RequestMapping reqMapping =
TestController.class.getAnnotation(RequestMapping.class);
String name = reqMapping.name(); //now name shoud have value as "/blog/"
另外,请确保将您的类标记为RetentionPolicy
为RUNTIME
@Retention(RetentionPolicy.RUNTIME)
您可以通过为其提供所需的包和注释来使用
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();
}
Reflections=newreflections(“my.project.prefix”);
设置尝试玉米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
}
}
List如果您使用的是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;
}
/**
*为给定注释类型创建新的{@link AnnotatedTypeScanner}。
*
*PARAM考虑是否要考虑接口。
*@param annotation键入要扫描的批注。
*/
public AnnotatedTypeScanner(boolean considerInterfaces,Class)通过使用Google Guice中的AOP库,您可以更轻松地使用反射。AOP是实现应用程序横切关注点的常用方法,如日志/跟踪、事务处理或权限检查
您可以在这里阅读更多信息:以下代码对我有用,下面的示例使用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());
}
}
你为什么要直接访问注释?你打算用它们做些什么吗?你只是想要一个包含这些注释的类的列表吗?我将获取requestmapping的值并将它们插入到一个字典中。可能的重复项我可以指定包,这不是问题或限制。非常困难???我会说,这是当你知道你的类路径时(你通常会这样做)。但我同意使用一个好的工具是一个好主意。如果你想有效地做这件事,这是非常困难的。特别是如果你不想为类路径上的所有类创建类实例。问题是如何“获得所有具有@Controller注释的类的列表”.检查单个类的注释是完全不同的事情。
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());
}
}