开发者社区> 问答> 正文

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

@WebService(targetNamespace = "http://zonepower.com/")
配置@WebService的targetNamespace需要读取配置文件中的值而非在代码中写死该如何实现呢?

展开
收起
蛮大人123 2016-03-10 17:31:41 4059 0
2 条回答
写回答
取消 提交回答
  • 十年前从 LNMP 开始个人站长 mengkang.net 生涯。 分享各种线上故障复盘笔记,关注我,防止采坑。
    配合反射来读取
    2019-07-17 18:58:01
    赞同 展开评论 打赏
  • 我说我不帅他们就打我,还说我虚伪

    下面的代码中会用Holder注解模拟WebService注解的行为来说明。
    首先需要另外一个Hacker注解用于解析到目标URL(目标endPoint),当然也可以是另外的方式,这里只是保持注解的解法。
    在原来的类上只设置Hacker注解,再通过动态解析的方式从Hacker注解解析到目标URL,利用这个URL构造一个Holder注解,最后加到原来的类上面。(先看结论!!!)

    Holder注解

    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注解

    @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类

    **
     * Created by Honwhy on 2016/2/4.
     */
    //@Holder
    @Hacker(Hacker.TargetType.DB)
    public class ExamplePojo {
        //other login
    }

    测试主类

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

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

    2019-07-17 18:58:01
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载