Java 将动态参数传递给注释
我想知道是否有可能将值动态传递给注释属性 我知道注释不是为了修改而设计的,但在我的例子中,我使用的和要放置的条件不是静态的 我认为唯一的解决方案是使用libraries,其目的是读取和修改字节码,如Javassist或,但如果有另一种解决方案,那就太好了 ps:在我的例子中,困难在于我应该修改注释(属性的值),但是我上面提到的库允许创建而不是编辑,这就是为什么我想找到另一个解决方案Java 将动态参数传递给注释,java,annotations,bytecode,javassist,hibernate-filters,Java,Annotations,Bytecode,Javassist,Hibernate Filters,我想知道是否有可能将值动态传递给注释属性 我知道注释不是为了修改而设计的,但在我的例子中,我使用的和要放置的条件不是静态的 我认为唯一的解决方案是使用libraries,其目的是读取和修改字节码,如Javassist或,但如果有另一种解决方案,那就太好了 ps:在我的例子中,困难在于我应该修改注释(属性的值),但是我上面提到的库允许创建而不是编辑,这就是为什么我想找到另一个解决方案 提前感谢注释参数是类文件中硬编码的常量。所以改变它们的唯一方法就是生成一个新的类文件 不幸的是,我不熟悉Hiber
提前感谢注释参数是类文件中硬编码的常量。所以改变它们的唯一方法就是生成一个新的类文件
不幸的是,我不熟悉Hibernate,因此我无法建议您的具体情况下的最佳选择。我不知道它是否与您的框架很好地集成,但我想提出以下建议:
- 创建一个注释,该注释接收实现验证规则的类
- 创建注释可以接收的接口
- 为具有规则逻辑的接口创建实现
- 将注释添加到模型类中
- 创建一个注释处理器,为每个注释字段应用验证
import java.lang.annotation.*
// Our Rule interface
interface Rule<T> { boolean isValid(T t) }
// Here is the annotation which can receive a Rule class
@Retention(RetentionPolicy.RUNTIME)
@interface Validation { Class<? extends Rule> value() }
// An implementation of our Rule, in this case, for a Person's name
class NameRule implements Rule<Person> {
PersonDAO dao = new PersonDAO()
boolean isValid(Person person) {
Integer mode = dao.getNameValidationMode()
if (mode == 1) { // Don't hardcode numbers; use enums
return person.name ==~ "[A-Z]{1}[a-z ]{2,25}" // regex matching
} else if (mode == 2) {
return person.name ==~ "[a-zA-Z]{1,25}"
}
}
}
注释的处理:
// Here we get each annotation and process it against the object
class AnnotationProcessor {
String validate(Person person) {
def annotatedFields = person.class.declaredFields.findAll { it.annotations.size() > 0 }
for (field in annotatedFields) {
for (annotation in field.annotations) {
Rule rule = annotation.value().newInstance()
if (! rule.isValid(person)) {
return "Error: name is not valid"
}
else {
return "Valid"
}
}
}
}
}
和测试:
// These two must pass
assert new AnnotationProcessor().validate(
new Person(name: "spongebob squarepants") ) == "Error: name is not valid"
assert new AnnotationProcessor().validate(
new Person(name: "John doe") ) == "Valid"
另外,请看一下,它通过模型注释提供了一些有趣的验证。您不能。我不明白你为什么要这么做。如果您知道要传递给它的值,只需使用它对带注释的字段进行操作。传递一个类参数并创建它的实例如何?@SotiriosDelimanolis:要传递的值取决于用户检查的内容,最初它是未知的;-)@威尔普:这是什么意思?@Issam,我的想法是使用类参数而不是值,但我怀疑它是否会与过滤器集成。类似于
@Valid(MyValidator.class)
。你是在JavaEE上还是在Spring上?您可以尝试类似于您所说的注释是硬编码在类文件中的。那么,是否有可能加载类文件并修改一些值?我不知道你是否明白我的意思?一旦加载,类文件是不可变的。但是,在加载它们之前,您可以随意更改它们。在编译时注释处理器中,如果annotation.value().newInstance()
可能无法工作,您该如何做?指
// These two must pass
assert new AnnotationProcessor().validate(
new Person(name: "spongebob squarepants") ) == "Error: name is not valid"
assert new AnnotationProcessor().validate(
new Person(name: "John doe") ) == "Valid"