[SPRING] Spring AOP : 인수 이름에 접근하기
SPRINGSpring AOP : 인수 이름에 접근하기
저는 Spring 3.x, Java 6을 사용하고 있습니다.
나는 다음 joinpoint를 가진 @Around aspect를 가진다.
@Around("execution(public * my.service.*.*Connector.*(..))")
그래서 저는 기본적으로 클래스 이름이 "Connector"로 끝나는 클래스의 공용 메소드에 대한 모든 호출을 인터셉트하는 것에 관심이 있습니다. 여태까지는 그런대로 잘됐다.
자, 내 측면에서 메서드의 실제 인수 이름에 액세스하고 싶습니다 :
public doStuff(String myarg, Long anotherArg)
myarg 및 anotherArg
나는 그것을 사용하는 것을 이해한다 :
CodeSignature signature = (CodeSignature)jointPoint.getSignature();
return signature.getParameterNames();
실제로 작동하지만, "-g"플래그 (전체 디버그)로 코드를 컴파일하고 오히려 수행하지 않을 경우에만 가능합니다.
이러한 종류의 런타임 정보에 액세스 할 수있는 다른 방법이 있습니까?
감사 엘
해결법
-
==============================
1.유감스럽게도 JVM / 바이트 코드의 잘 알려진 제한 사항입니다. 리플렉션을 사용하여 인수 이름을 얻을 수 없습니다. 메소드 이름 / 클래스 이름과는 달리 바이트 코드에 항상 저장되는 것은 아니기 때문에 리플렉션을 사용하여 인수 이름을 얻을 수 없습니다. .
유감스럽게도 JVM / 바이트 코드의 잘 알려진 제한 사항입니다. 리플렉션을 사용하여 인수 이름을 얻을 수 없습니다. 메소드 이름 / 클래스 이름과는 달리 바이트 코드에 항상 저장되는 것은 아니기 때문에 리플렉션을 사용하여 인수 이름을 얻을 수 없습니다. .
해결 방법으로 여러 프레임 워크 / 사양에서는 WebParam (이름 속성) 또는 PathParam과 같은 인수를 통해 사용자 지정 주석을 사용합니다.
주석없이 얻을 수있는 모든 시간은 가치의 배열입니다.
-
==============================
2.org.springframework.core.ParameterNameDiscoverer의 구현을 확인하십시오.
org.springframework.core.ParameterNameDiscoverer의 구현을 확인하십시오.
spring이 사용하는 @RequestParam과 같은 주석은 값이 설정되지 않은 경우 매개 변수 이름을 검사합니다. 따라서 @RequestParam String foo는 사실 "foo"라는 요청 매개 변수를 가져옵니다. ParameterNameDiscoverer 메커니즘을 사용합니다. 각 구현을 사용하여 어떤 구현을 사용하는지 확실하지 않습니다.
LocalVariableTableParameterNameDiscoverer는 .class를 읽고 asm을 사용하여 이름을 검사합니다.
그래서 가능합니다. 그러나이 정보를 캐시해야합니다 (예 : 키 = 클래스 + 메소드 + 매개 변수 색인과 함께 매개 변수 이름을 맵에 저장).
그러나 문서에서 언급했듯이 디버그 정보가 필요합니다. @PathVariable의 문서에서 :
그래서, 정말로 그 정보를 포함하고 싶지 않다면, Tomasz Nurkiewicz의 답은 그 해결 방법을 설명합니다.
-
==============================
3.Java 8에는 추가 메타 데이터를 바이트 코드와 함께 저장할 수있는 새로운 컴파일러 플래그가 있으며 이러한 매개 변수 이름은 리플렉션의 Parameter 객체를 사용하여 추출 할 수 있습니다. JDK 8 스펙을 참조하십시오. 최신 버전의 hibernate에서는 org.springframework.core.ParameterNameDiscoverer가이 기능을 사용한다. 이 플래그로 javac를 사용하여 컴파일하려면 다음을 수행하십시오.
Java 8에는 추가 메타 데이터를 바이트 코드와 함께 저장할 수있는 새로운 컴파일러 플래그가 있으며 이러한 매개 변수 이름은 리플렉션의 Parameter 객체를 사용하여 추출 할 수 있습니다. JDK 8 스펙을 참조하십시오. 최신 버전의 hibernate에서는 org.springframework.core.ParameterNameDiscoverer가이 기능을 사용한다. 이 플래그로 javac를 사용하여 컴파일하려면 다음을 수행하십시오.
-parameters Generate metadata for reflection on method parameters
리플렉션의 Parameter 클래스를 사용하여 매개 변수에 액세스합니다.
-
==============================
4.가장 좋은 방법인지 확실하지 않지만 내 방법에 대한 주석을 추가했습니다.
가장 좋은 방법인지 확실하지 않지만 내 방법에 대한 주석을 추가했습니다.
내 주석 :
@Retention (RetentionPolicy.RUNTIME) @Target (ElementType.METHOD) public @interface ReadApi { String[] paramNames() default ""; } @ReadApi (paramNames={"name","id","phone"}) public Address findCustomerInfo(String name, String id, String phone) { ..... }
그리고 측면 :
@Around("aspect param && @annotation(readApi)") public Object logParams(ProceedingJoinPoint pjp, ReadApi readApi) { //use pjp.getArgs() and readApi.paramNames(); }
이것은 아마 해킹이지만 정보를 얻기 위해 더 많은 옵션으로 컴파일하고 싶지 않았습니다. 어쨌든, 나를 위해 잘 작동합니다. 유일한 단점은 내가 주석과 메소드에서 이름을 동기화하여 유지해야한다는 것입니다.
from https://stackoverflow.com/questions/5030638/spring-aop-get-access-to-argument-names by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 대문자와 소문자를 구별하지 않는 Spring CrudRepository의 쿼리 (0) | 2019.02.08 |
---|---|
[SPRING] HiddenHttpMethodFilter가 활성화 된 후 Spring MVC 3.0.2를 사용하여 여러 파일 업로드하기 (0) | 2019.02.08 |
[SPRING] Spring Boot 앱에서 API 게이트웨이를 사용할 때 HATEOAS 경로가 유효하지 않습니다. (0) | 2019.02.08 |
[SPRING] Spring Security SAML + HTTPS를 다른 페이지로 (0) | 2019.02.08 |
[SPRING] 다중 컨텍스트에서 속성을 찾을 수 없습니다 : property-placeholder (0) | 2019.02.08 |