user2902211
user2902211

Reputation: 185

CGLib - create a bean with some fields and place annotations on them?

is it possible to generate a bean class that have a field annotated with specified annotations? I know that a bean can be created but what about annotations...? I cannot find anything about it so I have strong doubts about it and the only way to make sure is to ask here...

// I found something which may be helpful... please verify this code. It uses javassist capabilities.

    // pool creation
    ClassPool pool = ClassPool.getDefault();
    // extracting the class
    CtClass cc = pool.getCtClass(clazz.getName());
    // looking for the method to apply the annotation on
    CtField fieldDescriptor = cc.getDeclaredField(fieldName);
    // create the annotation
    ClassFile ccFile = cc.getClassFile();
    ConstPool constpool = ccFile.getConstPool();
    AnnotationsAttribute attr = new AnnotationsAttribute(constpool,
            AnnotationsAttribute.visibleTag);

    Annotation annot = new Annotation("sample.PersonneName", constpool);
    annot.addMemberValue("name",
            new StringMemberValue("World!! (dynamic annotation)", ccFile.getConstPool()));
    attr.addAnnotation(annot);

    // add the annotation to the method descriptor
    fieldDescriptor.getFieldInfo().addAttribute(attr);

The problem with it is that I don't know a way to apply existing annotation on the newly created type... is there a way to do that?

Upvotes: 1

Views: 2173

Answers (1)

Rafael Winterhalter
Rafael Winterhalter

Reputation: 44067

The short answer is no. Cglib by itself does not support such functionality. Cglib is quite old and its core was written before annotation were introduced to Java. Eversince, cglib was not maintained too much.

However, you can smuggle an ASM (the tool cglib is build upon) ClassVisitor into an Enhancer and add annotations manually. I would however recommend you to build your bean with ASM directly. For a simple POJO bean that is not a hard task and ASM is a great, well-maintained, well-documented tool. Cglib is not.

Update: You might want to have a look at my library Byte Buddy which is capable of serving your requirement. The following code would create a subclass of Object with a public field foo of type String with public visibility. This field was annotated by

@Retention(RetentionType.RUNTIME)
@interface MyAnnotation { }

class MyAnnotationImpl implements MyAnnotation {
  @Override
  public Class<? extends Annotation> annotationType() {
    return MyAnnotation.class;
  }
}

new ByteBuddy()
  .subclass(Object.class)
  .defineField("foo", String.class, MemberVisibility.PUBLIC)
  .annotateField(new MyAnnotationImpl())
  .make()
  .load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
  .getLoaded()
  .newInstance();

Upvotes: 5

Related Questions