dev2017. 3. 24. 11:18

http://stackoverflow.com/questions/14268981/modify-a-class-definitions-annotation-string-parameter-at-runtime/14276270#14276270


정말 별 짓을 다 한다 싶긴하지만, 경우에 따라 필요할 것 같은 기분이 들 때가 있다.

물론 어노테이션의 값을 runtime 에서 변경해가며 쓰는 것보다 더 나은 해법이 존재하겠지만,

어노테이션 기반으로 편리하게 제공되는 프레임워크를 별 다른 수정 없이 쓰기 위해선,

역시 이런 방법을 찾아보는 수 밖에 없다.


위 링크에 나와있는 정보는 내가 필요한 케이스에 대해서는 쓸 수는 없지만,

-

여러 세션이 동시 사용시 각 세션별로 그에 해당하는 값으로 처리되어야 하지만, 

위 링크 예시로는 오히려 서로 다른 값 설정으로 인해 의도치 않은 결과를 얻을 수 있어 적합하지 않다.

-

나름대로 이렇게 쓸 수도 있겠구나 하는 아이디어를 얻기엔 충분하다.


public static void main(String[] args) throws Exception {
    final Something oldAnnotation = (Something) Foobar.class.getAnnotations()[0];
    System.out.println("oldAnnotation = " + oldAnnotation.someProperty());
    Annotation newAnnotation = new Something() {

        @Override
        public String someProperty() {
            return "another value";
        }

        @Override
        public Class<? extends Annotation> annotationType() {
            return oldAnnotation.annotationType();
        }
    };
    Field field = Class.class.getDeclaredField("annotations");
    field.setAccessible(true);
    Map<Class<? extends Annotation>, Annotation> annotations = (Map<Class<? extends Annotation>, Annotation>) field.get(Foobar.class);
    annotations.put(Something.class, newAnnotation);

    Something modifiedAnnotation = (Something) Foobar.class.getAnnotations()[0];
    System.out.println("modifiedAnnotation = " + modifiedAnnotation.someProperty());
}

@Something(someProperty = "some value")
public static class Foobar {
}

@Retention(RetentionPolicy.RUNTIME)
@interface Something {

    String someProperty();
}

출처 : 위 링크



조금 더 검색해보다가 비슷한 고민을 했던 내용이 있어서 공유함.

@Transactional 같은 어노테이션을 새로 정의해서 재구현한 케이스.

http://neopatel.blogspot.kr/2012/04/java-spring-shard-datasource-with.html