Java 将动态参数传递给注释

Java 将动态参数传递给注释,java,annotations,bytecode,javassist,hibernate-filters,Java,Annotations,Bytecode,Javassist,Hibernate Filters,我想知道是否有可能将值动态传递给注释属性 我知道注释不是为了修改而设计的,但在我的例子中,我使用的和要放置的条件不是静态的 我认为唯一的解决方案是使用libraries,其目的是读取和修改字节码,如Javassist或,但如果有另一种解决方案,那就太好了 ps:在我的例子中,困难在于我应该修改注释(属性的值),但是我上面提到的库允许创建而不是编辑,这就是为什么我想找到另一个解决方案 提前感谢注释参数是类文件中硬编码的常量。所以改变它们的唯一方法就是生成一个新的类文件 不幸的是,我不熟悉Hiber

我想知道是否有可能将值动态传递给注释属性

我知道注释不是为了修改而设计的,但在我的例子中,我使用的和要放置的条件不是静态的

我认为唯一的解决方案是使用libraries,其目的是读取和修改字节码,如Javassist或,但如果有另一种解决方案,那就太好了

ps:在我的例子中,困难在于我应该修改注释(属性的值),但是我上面提到的库允许创建而不是编辑,这就是为什么我想找到另一个解决方案


提前感谢

注释参数是类文件中硬编码的常量。所以改变它们的唯一方法就是生成一个新的类文件


不幸的是,我不熟悉Hibernate,因此我无法建议您的具体情况下的最佳选择。

我不知道它是否与您的框架很好地集成,但我想提出以下建议:

  • 创建一个注释,该注释接收实现验证规则的类
  • 创建注释可以接收的接口
  • 为具有规则逻辑的接口创建实现
  • 将注释添加到模型类中
  • 创建一个注释处理器,为每个注释字段应用验证
我用Groovy编写了以下示例,但使用的是标准Javalibs和惯用Java。如果有无法读取的内容,请警告我:

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"