我有一个简单的jane servlets Web应用程序,我的一些类有以下注释:
@Controller
@RequestMapping(name = "/blog/")
public class TestController {
..
}
现在,当我的servlet应用程序启动时,我希望获得所有具有@Controller注释的类的列表,然后获取@RequestMapping注释的值并将其插入字典中。
我该怎么做?
我也在使用Guice和Guava,但不确定是否有任何与注释相关的助手。
答案 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)