简体   繁体   English

用字节码创建注释,但是我的代码找不到注释

[英]Creating annotations with byte-buddy but my code can't find the annotations

Currently I'm trying to generate my classes for my Tests via this: 目前,我正在尝试通过以下方式为测试生成类:

AnnotationDescription entity = AnnotationDescription.Builder.ofType(Entity.class) //
    .build();

AnnotationDescription table = AnnotationDescription.Builder.ofType(Table.class) //
    .define("name", "FIRST_TABLE") //
    .build();

// @Column ( name = "X1", length = 20 )
AnnotationDescription nameAnnotationColumn = AnnotationDescription.Builder.ofType(Column.class) //
    .define("name", "X1") //
    .define("length", 20) //
    .build();

// @Column ( name = "X1", length = 20 )
AnnotationDescription nameAnnotationKeyColumn = AnnotationDescription.Builder.ofType(Column.class) //
    .define("name", "ADR_EXTERN_KEY") //
    .define("precision", 15) //
    .build();
Class<? extends Serializable> subclass = new ByteBuddy().subclass(Serializable.class) //
    .annotateType(entity, table) //
    .defineField("name", String.class, Visibility.PRIVATE).annotateField(nameAnnotationColumn) //
    .defineMethod("getName", String.class, Visibility.PUBLIC).intercept(FieldAccessor.ofField("name")) //
    .defineField("key", BigDecimal.class, Visibility.PRIVATE).annotateField(nameAnnotationKeyColumn) //
    .defineMethod("getKey", BigDecimal.class, Visibility.PUBLIC).intercept(FieldAccessor.ofField("key")) //
    .make() //
    .load(getClass().getClassLoader()) //
    .getLoaded();

But my own code is trying to identify a class which should have an annotation like @Entity and @Table(name = "XXX") . 但是我自己的代码试图识别一个类,该类应具有@Entity@Table(name = "XXX")类的注释。 So the call to .annotatypeType(..) seemed to be either doing something I don't understand or I just create the annotations in a wrong way.. 因此,对.annotatypeType(..)的调用似乎在做我不了解的事情,或者只是以错误的方式创建了注释。

The code which tries to identify if the classes contain the @Entity and @Table annotation is in general like this: 尝试识别类是否包含@Entity@Table批注的代码通常如下所示:

public class X {
  private Class<? extends Serializable> givenClass;

  ...

if (hasAnnotation(this.givenClass.getClass().getAnnotations(), Entity.class)) {
 ....
}

where the method looks like this: 该方法如下所示:

  private boolean hasAnnotation(Annotation[] annotations, Object annotationToBeExistent) {

    boolean result = false;
    for (int i = 0; i < annotations.length; i++) {
      if (annotations[i].annotationType().equals(annotationToBeExistent)) {
        result = true;
      }
    }
    return result;

If I create a class manually and implement is as usual the code finds the annotations...So I think my mistake must be somewhere in using byte-buddy ? 如果我手动创建一个类并像往常一样实现,则代码会找到注释...所以我认为我的错误一定是在使用字节伙伴时出现的?

Update : 更新

After thinking about it and the comment I found out that my creation was wrong it must look like this instead: 在考虑了它和评论之后,我发现我的创作是错误的,它必须看起来像这样:

Serializable subclass = new ByteBuddy().subclass(Object.class) //
    .implement(Serializable.class)
    .annotateType(entity, table) //

But my code will not see the created annotations? 但是我的代码看不到创建的注释吗?

Update 2: 更新2:

So after your comments/suggestions (which helped a lot; Thanks for the support) I have drilled down my problem to the following code snippet: I assume my usage of AnnotationDescription or creating the annotation is not correct cause the assert will result in false . 因此,在您提出了意见/建议(这很有帮助;感谢您的支持)之后,我将问题细化为以下代码片段:我认为我对AnnotationDescription的使用或创建注释不正确,因为assert会导致false

AnnotationDescription entity = AnnotationDescription.Builder.ofType(Entity.class) //
    .build();

Serializable subclass = new ByteBuddy().subclass(Object.class) //
    .implement(Serializable.class)
    .annotateType(entity) //
    .make() //
    .load(this.getClass().getClassLoader()) //
    .getLoaded();

assertThat(subclass.getClass().isAnnotationPresent(Entity.class)).isTrue(); assertThat(subclass.getClass()。isAnnotationPresent(Entity.class))。isTrue();

Your API use is correct and I could even validate the working by invoking: 您的API使用是正确的,我什至可以通过调用以下方法来验证其工作:

subclass.isAnnotationPresent(Entity.class)

on your resulting class. 在你的课上。 I assume that there is a problem in your scanning logic. 我认为您的扫描逻辑有问题。 Some tools scan classes by introspecting class files from jars directly, maybe this is the reason that you cannot locate the class? 一些工具通过直接从jars内省类文件来扫描类,也许这是您无法找到类的原因?

As for your update, are you expecting for Byte Buddy to return an instance? 至于您的更新,您是否希望Byte Buddy返回实例? Byte Buddy only generates classes and Class types implement the Serializable interface which is why your code compiles to begin with: Byte Buddy仅生成类,并且Class类型实现Serializable接口,这就是为什么您的代码从以下几点开始编译的原因:

AnnotationDescription entity = AnnotationDescription.Builder
    .ofType(Entity.class)
    .build();

Class<?> subclass = new ByteBuddy().subclass(Object.class)
  .implement(Serializable.class)
  .annotateType(entity)
  .make()
  .load(this.getClass().getClassLoader())
  .getLoaded();

Now, the resulting class should carry your expected annotation. 现在,结果类应该带有您期望的注释。 You can use reflection to create an instance that implements the Serializable interface. 您可以使用反射来创建实现Serializable接口的实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM