首页 > Java:Annotation中如何读取动态配置值?

Java:Annotation中如何读取动态配置值?

@WebService(targetNamespace = "http://zonepower.com/")

配置@WebService的targetNamespace需要读取配置文件中的值而非在代码中写死该如何实现呢?


我感觉是做不到的。
不过如果要做到动态化这点,需要调整注解@WebService的运行时机。
至少是RetentionPolicy.RUNTIME形式。

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

Holder注解

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());
    }
}

结论

上述解法无效!!!

参考链接:
[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


自定义一个或者重写一个

【热门文章】
【热门文章】