java - 为什么 Weld 需要 AnnotationLiteral 而不是 Annotation 类?
问题描述
我只是尝试使用限定符从 CDI 检索对象。
private static class QualifierLiteral
extends AnnotationLiteral<RandomQualifier>
implements RandomQualifier {
}
QualifierLiteral QUALIFIER = new QualifierLiteral();
CDI.current().select(TranslationProvider.class, QUALIFIER).get()
RandomQualifier.class
我想知道,它不在这里的原因是什么?
有什么理由,为什么他们需要文字的实例而不仅仅是类?
(问题的范围是了解weld/cdi/java的内部工作原理)
解决方案
Weld 支持带有成员(注释元素)的限定符。如果你只能传递Class
参数,它就无法做到这一点。相反,select
需要一个可以为这些成员提供预期值的注释实例。
请记住,注释类型只是接口。因此,您可以为它们创建子类并实例化它们。例如,假设你RandomQualifier
看起来像
@interface RandomQualifier {
int randomNumber();
}
你可以有
class RandomQualifierImpl implements RandomQualifier {
@Override
public Class<? extends Annotation> annotationType() {
return RandomQualifier.class;
}
@Override
public int randomNumber() {
return 4;
}
}
通常,当您使用注释对类(或其他任何东西)进行注释并使用反射提取该注释时,JVM 负责创建实现这些方法的动态子类并返回相应的实例。但在这里,我们必须自己做。
为方便起见,CDI 框架AnnotationLiteral
作为帮助类提供了annotationType()
使用类型标记“hack”的实现。
这样,您可以简单地编写
class RandomQualifierImpl extends AnnotationLiteral<RandomQualifier> implements RandomQualifier {
@Override
public int randomNumber() {
return 4;
}
}
并RandomQualifierImpl
为select
.
或者,如果您根本不需要注释元素(成员),请使用匿名子类
Annotation instance = new AnnotationLiteral<RandomQualifier>() {};
推荐阅读
- swift - 使用 pod 时重复 info.plist 文件
- android - 反应原生:上传 apk 后,Play 商店有权限问题(CAMERA,RECORD_AUDIO,...)
- php - 具有多个阵列的在线服务器检测
- php - 在 Woocommerce 中自定义我的帐户地址字段
- c# - 如何备份迁移文件夹
- android - 使用工作管理器获取远程异常
- vue.js - Buefy 自动完成搜索 在右侧添加清除图标?
- django - 如果已经创建了对象,则 Django CreateView 重定向到 UpdateView
- javascript - Node JS对后端API的多个并发请求
- java - 如何检索 ArrayList (Java) 的索引?