package com.honey.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by Honwhy on 2016/2/3.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Holder {
String value() default "";
}
Hacker註解
package com.honey.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by Honwhy on 2016/2/3.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Hacker {
public enum TargetType {
NULL("NULL"), DB("DB"), XML("XML");
private final String type;
TargetType(String type) {
this.type = type;
}
public String getTarget() {
String target = "";
switch (this) {
case NULL:
break;
case DB:
// get from db
target = "db";
break;
case XML:
// get from xml
target = "xml";
break;
}
return target;
}
}
TargetType value() default TargetType.NULL;
}
ExamplePojo 普通POJO類
package com.honey.annotation;
/**
* Created by Honwhy on 2016/2/4.
*/
//@Holder
@Hacker(Hacker.TargetType.DB)
public class ExamplePojo {
//other login
}
測試主類
package com.honey.annotation;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
import javassist.bytecode.AnnotationsAttribute;
import javassist.bytecode.ClassFile;
import javassist.bytecode.ConstPool;
import javassist.bytecode.annotation.StringMemberValue;
import java.lang.annotation.Annotation;
import static javassist.bytecode.AnnotationsAttribute.visibleTag;
/**
* learn from http://ayoubelabbassi.blogspot.jp/2011/01/how-to-add-annotations-at-runtime-to.html
* another example http://prismoskills.appspot.com/lessons/Super_Java/Dynamically_adding_annotations.jsp
* Created by Honwhy on 2016/2/4.
*/
public class HackerTest {
public static void main(String[] args) throws NotFoundException, ClassNotFoundException {
HackerTest test = new HackerTest();
//test.parsePojo();
test.doHack();
test.parsePojo();
}
/**
* hack方法
* 动态修改注解
*/
private void doHack() throws NotFoundException, ClassNotFoundException {
//pool creation
ClassPool pool = ClassPool.getDefault();
//extracting the class
CtClass cc = pool.getCtClass("com.honey.annotation.ExamplePojo");
Class<?> clazz = ExamplePojo.class;
final Annotation annotation = clazz.getAnnotation(Hacker.class);
Hacker hacker = (Hacker) annotation;
final String targetUrl = hacker.value().getTarget();
System.out.println("targetUrl : " + targetUrl);
//hack ExamplePojo's Holder Annotation
/*Annotation newAnnotation = new Annotation() {
@Override
public Class<? extends Annotation> annotationType() {
return annotations[0].annotationType();
}
public String value() {
return targetUrl;
}
};*/
// create the annotation
ClassFile ccFile = cc.getClassFile();
ConstPool constpool = ccFile.getConstPool();
AnnotationsAttribute attr = new AnnotationsAttribute(constpool, visibleTag);
javassist.bytecode.annotation.Annotation annot = new javassist.bytecode.annotation.Annotation("com.honey.annotation.Holder", constpool);
annot.addMemberValue("value", new StringMemberValue(targetUrl,ccFile.getConstPool()));
annot.addMemberValue("name", new StringMemberValue(targetUrl,ccFile.getConstPool()));
attr.addAnnotation(annot);
ccFile.addAttribute(attr);
//ccFile.setVersionToJava5();
}
/**
* 打印Target注解
*/
private void parsePojo() {
Class<?> clazz = ExamplePojo.class;
Annotation annotation = clazz.getAnnotation(Holder.class);
Holder target = (Holder) annotation;
System.out.println("ExamplePojo with annotation target, value is: " + target.value());
}
}
我覺得是做不到的。
不過如果要做到動態化這一點,就需要調整註解
@WebService
的運作時機。@WebService
的运行时机。至少是
RetentionPolicy.RUNTIME
形式。UPDATE
先不论题主是否已经找到其他方式来完成这样的需求,不一定是从注解的角度去解决的。
我这里把我的思路说下,下面的代码中会用
Holder
注解模拟WebService
注解的行为来说明。首先需要另外一个
Hacker
注解用于解析到目标URL(目标endPoint),当然也可以是另外的方式,这里只是保持注解的解法。在原来的类上只设置
Hacker
注解,再通过动态解析的方式从Hacker
注解解析到目标URL,利用这个URL构造一个Holder
至少是RetentionPolicy.RUNTIME
形式。UPDATE
先不論題主是否已經找到其他方式來完成這樣的需求,不一定是從註解的角度去解決的。我這裡把我的思路說下,下面的程式碼中會用
首先需要另一個Holder
註解模擬WebService
註解的行為來說明。Hacker
註解用於解析到目標URL(目標endPoint),當然也可以是另外的方式,這裡只是保持註解的解法。在原來的類別上只設定
Hacker
註解,再透過動態解析的方式從Hacker
註解解析到目標URL,利用這個URL建構一個Holder code>註解,最後加到原來的類別上面。 (先看結論!!!)
Holder註解
Hacker註解
ExamplePojo 普通POJO類
測試主類
結論
🎜附🎜 🎜參考連結:🎜[1] http://ayoubelabbassi.blogspot.jp/2011/01/how-to-add-annotations-at-runtime-to.html🎜[2] http://prismoskills.appspot.com /lessons/Super_Java/Dynamically_adding_annotations.jsp🎜上述解法無效! ! !
自訂一個或重寫一個