3

Javassist を使用して実行時に JAXB アノテーションを挿入しようとしています。私は次のコードを書きました:

public class AssistAnnotationInjector {
public static void addAnnotationRunTime(String className, String fieldName) throws NotFoundException, CannotCompileException, IOException, ClassNotFoundException{

    CtClass ctClass = ClassPool.getDefault().get(className);
    ClassFile ccFile = ctClass.getClassFile();
    ConstPool constPool = ccFile.getConstPool();
    AnnotationsAttribute attr = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);
    Annotation annot = new Annotation("javax.xml.bind.annotation.XmlTransient",constPool);
    attr.addAnnotation(annot);
    CtField field = ctClass.getDeclaredField(fieldName);
    field.getFieldInfo().addAttribute(attr);
    System.out.println(field.getAnnotation(XmlTransient.class));
    ccFile.setVersionToJava5();
    ctClass.writeFile();
}

public static void main (String args[]) throws CannotCompileException, NotFoundException, IOException, SecurityException, NoSuchMethodException, ClassNotFoundException, JAXBException, NoSuchFieldException{
    Person<Student> p = new Person<Student>();
    p.setName("XYZ");
    Student s = new Student();
    s.setName("ABC");
    s.setId("239423");
    p.setPayload(s);

    addAnnotationRunTime("RuntimeAnnotation.Person", "name");

    Field f = p.getClass().getDeclaredField("name");
    System.out.println(f.getAnnotation(XmlTransient.class));

    JAXBContext context = JAXBContext.newInstance(p.getClass());

      Marshaller mr = context.createMarshaller();
      mr.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

      mr.marshal(p, System.out);
}
}

Person.java クラスは次のとおりです。

@XmlRootElement(name="Person")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso({Student.class})
public class Person <T>{

private T payload;

private String name;

public void setPayload(T payload){
    this.payload = payload;
}

public T getPayload(){
    return payload;
}

public void setName(String name){
    this.name = name;
}

public String getName(){
    return name;
}
}

AssistAnnotationInjector.java で、'name' フィールドに XmlTransient アノテーションを追加しようとしています。しかし、名前フィールドはまだマーシャリング出力に入っています。なぜそうなのですか?

PS: マーシャル出力は次のとおりです。

@javax.xml.bind.annotation.XmlTransient
null
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Person>
<payload xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="student">
    <name>ABC</name>
    <id>239423</id>
</payload>
**<name>XYZ</name>**
</Person>

名前タグは出力に存在することが予期されていませんでした..

4

2 に答える 2

0

基本的に 2 つのオプションがあります。

  1. クラスをロードするに変更を行ってください。通常の方法でリフレクションを使用することはできません! Maven プラグインで org.reflections を使用して、クラスをプリフェッチすることができます。詳細については、こちらを参照してください。

  2. カスタム クラスローダーを使用して、変更されたクラスをロードします。詳細については、こちらを参照してください。

于 2013-04-24T21:03:10.647 に答える
0

フィールドに属性を追加した後、クラスをフリーズする ctClass.toClass() メソッドを呼び出す必要があります。この後、注釈を確認できます。

于 2015-04-21T10:19:09.467 に答える