search

Home  >  Q&A  >  body text

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

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

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

天蓬老师天蓬老师2806 days ago848

reply all(2)I'll reply

  • 伊谢尔伦

    伊谢尔伦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构造一个HolderAt least in the form of RetentionPolicy.RUNTIME.

    UPDATE

    Regardless of whether the questioner has found other ways to complete such a requirement, it may not necessarily be solved from the perspective of annotations.

    I will explain my thoughts here. The following code will use the Holder annotation to simulate the behavior of the WebService annotation.

    First, another 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.

    Only set the 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 annotation, and finally added to the original class. (Read the conclusion first!!!)

    Holder annotation

    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 Notes

    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
    }
    

    Test main class

    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! ! !

    🎜Attached🎜 🎜Reference links: 🎜[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🎜

    reply
    0
  • ringa_lee

    ringa_lee2017-04-17 17:00:51

    Customize one or rewrite one

    reply
    0
  • Cancelreply