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
的运行时机。至少是
RetentionPolicy.RUNTIME
形式。UPDATE
先不论题主是否已经找到其他方式来完成这样的需求,不一定是从注解的角度去解决的。
我这里把我的思路说下,下面的代码中会用
Holder
注解模拟WebService
注解的行为来说明。首先需要另外一个
Hacker
注解用于解析到目标URL(目标endPoint),当然也可以是另外的方式,这里只是保持注解的解法。在原来的类上只设置
Hacker
注解,再通过动态解析的方式从Hacker
注解解析到目标URL,利用这个URL构造一个Holder
注解,最后加到原来的类上面。(先看结论!!!)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
自定义一个或者重写一个