Maison  >  Questions et réponses  >  le corps du texte

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

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

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

天蓬老师天蓬老师2764 Il y a quelques jours804

répondre à tous(2)je répondrai

  • 伊谢尔伦

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

    我感觉是做不到的。
    不过如果要做到动态化这点,需要调整注解@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

    répondre
    0
  • ringa_lee

    ringa_lee2017-04-17 17:00:51

    自定义一个或者重写一个

    répondre
    0
  • Annulerrépondre