Alo*_*tor 243 java annotations classloader
搜索带注释类的整个类路径的最佳方法是什么?
我正在做一个库,我想允许用户注释他们的类,所以当Web应用程序启动时,我需要扫描整个类路径以获取某些注释.
你知道一个库或Java工具吗?
编辑:我正在考虑类似Java EE 5 Web服务或EJB的新功能.您使用@WebServiceor 注释您的类,@EJB并且系统在加载时查找这些类,以便远程访问它们.
Art*_*ald 203
使用org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider
API
从基础包扫描类路径的组件提供程序.然后,它会对结果类应用排除和包含过滤器以查找候选项.
ClassPathScanningCandidateComponentProvider scanner =
new ClassPathScanningCandidateComponentProvider(<DO_YOU_WANT_TO_USE_DEFALT_FILTER>);
scanner.addIncludeFilter(new AnnotationTypeFilter(<TYPE_YOUR_ANNOTATION_HERE>.class));
for (BeanDefinition bd : scanner.findCandidateComponents(<TYPE_YOUR_BASE_PACKAGE_HERE>))
System.out.println(bd.getBeanClassName());
Run Code Online (Sandbox Code Playgroud)
Jon*_*han 142
另一个解决方案是谷歌的反思.
快速复审:
Luk*_*son 41
您可以使用ClassGraph查找具有任何给定注释的类,以及搜索其他感兴趣的标准,例如实现给定接口的类.(免责声明,我是ClassGraph的作者.)ClassGraph可以在内存中为类路径上的所有类或类中的类构建整个类图(所有类,注释,方法,方法参数和字段)的抽象表示.列入白名单的软件包,您可以根据需要查询该类图.ClassGraph支持比任何其他扫描程序更多的类路径规范机制和类加载器,并且还可以与新的JPMS模块系统无缝协作,因此如果您将代码基于ClassGraph,您的代码将最大程度地可移植.请在此处查看API.
rmu*_*ler 23
如果你想要一个真正重量轻(无依赖性,简单的API,15 kb的jar文件)和非常快的解决方案,来看看annotation-detector在发现https://github.com/rmuller/infomas-asl
免责声明:我是作者.
Sła*_*wek 18
您可以使用Java Pluggable Annotation Processing API编写将在编译过程中执行的注释处理器,并将收集所有带注释的类并构建索引文件以供运行时使用.
这是进行带注释的类发现的最快方法,因为您不需要在运行时扫描类路径,这通常是非常慢的操作.此方法也适用于任何类加载器,而不仅适用于运行时扫描程序通常支持的URLClassLoaders.
上述机制已在ClassIndex库中实现.
要使用它,请使用@IndexAnnotated元注释来注释自定义注释.这将在编译时创建一个索引文件:META-INF/annotations/com/test/YourCustomAnnotation列出所有带注释的类.您可以通过执行以下命令在运行时访问索引:
ClassIndex.getAnnotated(com.test.YourCustomAnnotation.class)
Run Code Online (Sandbox Code Playgroud)
zapp有一个很棒的评论,包含在所有这些答案中:
new Reflections("my.package").getTypesAnnotatedWith(MyAnnotation.class)
Run Code Online (Sandbox Code Playgroud)
是不是来不及回答了。我会说,最好使用ClassPathScanningCandidateComponentProvider或Scannotations 之类的库
但即使有人想用 classLoader 尝试一些实践,我还是自己写了一些来打印包中类的注释:
public class ElementScanner {
public void scanElements(){
try {
//Get the package name from configuration file
String packageName = readConfig();
//Load the classLoader which loads this class.
ClassLoader classLoader = getClass().getClassLoader();
//Change the package structure to directory structure
String packagePath = packageName.replace('.', '/');
URL urls = classLoader.getResource(packagePath);
//Get all the class files in the specified URL Path.
File folder = new File(urls.getPath());
File[] classes = folder.listFiles();
int size = classes.length;
List<Class<?>> classList = new ArrayList<Class<?>>();
for(int i=0;i<size;i++){
int index = classes[i].getName().indexOf(".");
String className = classes[i].getName().substring(0, index);
String classNamePath = packageName+"."+className;
Class<?> repoClass;
repoClass = Class.forName(classNamePath);
Annotation[] annotations = repoClass.getAnnotations();
for(int j =0;j<annotations.length;j++){
System.out.println("Annotation in class "+repoClass.getName()+ " is "+annotations[j].annotationType().getName());
}
classList.add(repoClass);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* Unmarshall the configuration file
* @return
*/
public String readConfig(){
try{
URL url = getClass().getClassLoader().getResource("WEB-INF/config.xml");
JAXBContext jContext = JAXBContext.newInstance(RepositoryConfig.class);
Unmarshaller um = jContext.createUnmarshaller();
RepositoryConfig rc = (RepositoryConfig) um.unmarshal(new File(url.getFile()));
return rc.getRepository().getPackageName();
}catch(Exception e){
e.printStackTrace();
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
在 config File 中,您将包名放入并将其解组为 class 。
Spring 有一种叫做AnnotatedTypeScanner类的东西。
这个类内部使用
ClassPathScanningCandidateComponentProvider
Run Code Online (Sandbox Code Playgroud)
此类具有用于实际扫描类路径资源的代码。它通过使用运行时可用的类元数据来做到这一点。
可以简单地扩展这个类或使用相同的类进行扫描。下面是构造函数定义。
/**
* 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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
156742 次 |
| 最近记录: |