搜尋

首頁  >  問答  >  主體

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

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

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

天蓬老师天蓬老师2807 天前853

全部回覆(2)我來回復

  • 伊谢尔伦

    伊谢尔伦2017-04-17 17:00:51

    我覺得是做不到的。
    不過如果要做到動態化這一點,就需要調整註解@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註解,最後加到原來的類別上面。 (先看結論!!!)

    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🎜

    回覆
    0
  • ringa_lee

    ringa_lee2017-04-17 17:00:51

    自訂一個或重寫一個

    回覆
    0
  • 取消回覆