찾다

 >  Q&A  >  본문

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

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

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

天蓬老师天蓬老师2825일 전868

모든 응답(2)나는 대답할 것이다

  • 伊谢尔伦

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

    불가능하다고 느껴집니다.
    그러나 이를 동적으로 달성하려면 @WebService 주석의 실행 타이밍을 조정해야 합니다.
    적어도 RetentionPolicy.RUNTIME 형식이어야 합니다.

    업데이트
    질문자가 이러한 요구 사항을 충족하기 위한 다른 방법을 찾았는지 여부에 관계없이 주석의 관점에서 반드시 해결되지 않을 수도 있습니다.
    여기서 내 생각을 설명하겠습니다. 다음 코드는 Holder 주석을 사용하여 WebService 주석의 동작을 시뮬레이션합니다.
    먼저 대상 URL(대상 endPoint)을 구문 분석하려면 또 다른 Hacker 주석이 필요합니다. 물론 주석을 유지하는 다른 방법도 있습니다.
    원래 클래스에 Hacker 주석만 설정한 다음 동적 구문 분석을 통해 Hacker 주석을 대상 URL로 구문 분석하고 이 URL을 사용하여 를 구성합니다. 홀더 주석을 추가하고 최종적으로 원래 클래스에 추가했습니다. (결론부터 먼저 읽어보세요!!!)

    홀더 주석

    package com.honey.annotation;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * Honwhy가 2016년 2월 3일에 작성함.
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(요소 유형.TYPE)
    공개 @인터페이스 보유자 {
        문자열 값() 기본값 "";
    }

    해커 노트

    package com.honey.annotation;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * Honwhy가 2016년 2월 3일에 작성함.
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(요소 유형.TYPE)
    공개 @interface 해커 {
        공개 열거형 TargetType {
            NULL("NULL"), DB("DB"), XML("XML");
    
            비공개 최종 문자열 유형;
    
            TargetType(문자열 유형) {
                this.type = 유형;
            }
    
            공개 문자열 getTarget() {
                문자열 대상 = "";
                스위치 (이것) {
                    NULL인 경우:
                        부서지다;
                    사례 DB:
                        //db에서 가져오기
                        타겟 = "db";
                        부서지다;
                    사례 XML:
                        //xml에서 가져오기
                        대상 = "xml";
                        부서지다;
                }
                반환 대상;
            }
    
        }
    
        TargetType 값() 기본값 TargetType.NULL;
    }
    

    ExamplePojo 일반 POJO 클래스

    package com.honey.annotation;
    
    /**
     * Honwhy가 2016년 2월 4일에 작성함.
     */
    //@보유자
    @Hacker(Hacker.TargetType.DB)
    공개 클래스ExamplePojo {
        //다른 로그인
    }
    

    메인 클래스 테스트

    package com.honey.annotation;
    
    import javassist.ClassPool;
    import javassist.CtClass;
    import javassist.NotFoundException;
    javassist.bytecode.AnnotationsAttribute를 가져옵니다.
    javassist.bytecode.ClassFile 가져오기;
    import javassist.bytecode.ConstPool;
    import javassist.bytecode.annotation.StringMemberValue;
    
    import java.lang.annotation.Annotation;
    
    정적 javassist.bytecode.AnnotationsAttribute.visibleTag 가져오기;
    
    /**
     * http://ayoubelabbassi.blogspot.jp/2011/01/how-to-add-annotations-at-runtime-to.html에서 알아보세요.
     * 또 다른 예 http://prismoskills.appspot.com/lessons/Super_Java/Dynamically_adding_annotations.jsp
     * Honwhy가 2016년 2월 4일에 작성함.
     */
    공개 클래스 HackerTest {
        public static void main(String[] args)에서 NotFoundException, ClassNotFoundException이 발생합니다.
            HackerTest 테스트 = new HackerTest();
            //test.parsePojo();
            test.doHack();
            test.parsePojo();
    
        }
    
        /**
         *해킹 방법
         * 주석을 동적으로 수정
         */
        private void doHack()은 NotFoundException, ClassNotFoundException을 발생시킵니다.
    
            //풀 생성
            ClassPool 풀 = ClassPool.getDefault();
            //클래스 추출
            CtClass cc = pool.getCtClass("com.honey.annotation.ExamplePojo");
            클래스 clazz = examplePojo.class;
            최종 주석 주석 = clazz.getAnnotation(Hacker.class);
            해커 해커 = (해커) 주석;
            final String targetUrl = hacker.value().getTarget();
            System.out.println("targetUrl : " + targetUrl);
    
            //예제Pojo의 홀더 주석 해킹
            /*주석 newAnnotation = new Annotation() {
                @보수
                공개 클래스 주석 유형() {
                    주석[0].annotationType()을 반환합니다.
                }
                공개 문자열 값() {
                    targetUrl을 반환합니다.
                }
            };*/
    
            // 주석을 생성합니다.
            클래스파일 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();
        }
    
        /**
         * 인쇄 대상 주석
         */
        개인 무효 파싱포조() {
            클래스 clazz = examplePojo.class;
            주석 주석 = clazz.getAnnotation(Holder.class);
            홀더 대상 = (홀더) 주석;
            System.out.println("주석 대상이 있는 예제Pojo, 값은 다음과 같습니다: " + 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
  • 취소회신하다