@WebService(targetNamespace = "http://zonepower.com/")
配置@WebService的targetNamespace需要读取配置文件中的值而非在代码中写死该如何实现呢?
伊谢尔伦2017-04-17 17:00:51
I feel like it’s impossible.
However, if you want to achieve this dynamically, you need to adjust the running timing of the annotation @WebService
. @WebService
的运行时机。
至少是RetentionPolicy.RUNTIME
形式。
UPDATE
先不论题主是否已经找到其他方式来完成这样的需求,不一定是从注解的角度去解决的。
我这里把我的思路说下,下面的代码中会用Holder
注解模拟WebService
注解的行为来说明。
首先需要另外一个Hacker
注解用于解析到目标URL(目标endPoint),当然也可以是另外的方式,这里只是保持注解的解法。
在原来的类上只设置Hacker
注解,再通过动态解析的方式从Hacker
注解解析到目标URL,利用这个URL构造一个Holder
At least in the form of RetentionPolicy.RUNTIME
.
Holder
annotation to simulate the behavior of the WebService
annotation. Hacker
annotation is needed to parse to the target URL (target endPoint). Of course, it can also be done in another way. Here is just the solution to keep the annotation. Hacker
annotation on the original class, then parse the Hacker
annotation to the target URL through dynamic parsing, and use this URL to construct a Holder code> annotation, and finally added to the original class. (Read the conclusion first!!!)
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 "";
}
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 ordinary POJO class
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());
}
}
Conclusion
The above solution is invalid! ! !