将动态参数传递给注解 [英] Passing dynamic parameters to an annotation

查看:119
本文介绍了将动态参数传递给注解的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I wonder if there is a possiblity to pass dynamically values to an annotation attribute.

我知道注释不是为了修改而设计的,但我正在使用 休眠过滤器 和条件在我的情况下不是静态的.

I know that annotation are not designed to be modified but I'm using Hibernate Filters and condition to be put are not static in my case.

我认为唯一的解决方案是使用旨在读取和修改字节码的库,例如 Javassist 或 ASM 但如果有其他解决方案就更好了.

I think that the only solution is to use librairies whose aim is to read and modify byte code such as Javassist or ASM but it would be too much better if there is another solution.

ps:就我而言,困难在于我应该修改注释(属性的值),但我上面提到的库允许创建而不是编辑,这就是我想知道另一个解决方案的原因

ps: The difficulty in my case is that I should modify annotations (attribute's value) but librairies I mentioned above allow to create not to edit that's why I'm wondering for another solution

提前致谢

推荐答案

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

I don't know if it integrates nicely with your frameworks, but i would like to suggest the following:

  • 创建一个注解,接收一个实现验证规则的类
  • 创建一个注解可以接收的接口
  • 为具有规则逻辑的接口创建一个实现
  • 将注释添加到您的模型类
  • 创建一个注释处理器,为每个注释字段应用验证

我在 Groovy 中编写了以下示例,但使用了标准的 Java 库和惯用的 Java.如果有任何不可读的内容,请警告我:

I wrote the following example in Groovy, but using standard Java libs and idiomatic Java. Warn me if anything is unreadable:

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}"
    }
  }
}

在这些声明之后,用法:

After these declarations, the usage:

// Our model with an annotated field
class Person {
  @Validation(NameRule.class)
  String name
}

// Here we are mocking a database select to get the rule save in the database
// Don't use hardcoded numbers, stick to a enum or anything else
class PersonDAO { Integer getNameValidationMode() { return 1 } }

注解的处理:

// 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"

另外,看看 GContracts,它提供了一些有趣的通过注解验证的模型.

Also, take a look at GContracts, it provides some interesting validation-through-annotations model.

这篇关于将动态参数传递给注解的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆