복붙노트

[SPRING] Spring AOP가 작동하지 않습니다. 메소드가 bean 내부에서 호출 될 때

SPRING

Spring AOP가 작동하지 않습니다. 메소드가 bean 내부에서 호출 될 때

내 응용 프로그램에 여러 개의 Aspect가 코딩되어 있습니다. 다른 모든 것은 다음을 제외하고 작동합니다.

서비스 인터페이스

package com.enbiso.proj.estudo.system.service;
...
public interface MessageService {
     ...
     Message reply(Message message);
     Message send(Message message);
     ...
}

서비스 구현

package com.enbiso.proj.estudo.system.service.impl;
....
@Service("messageService")
public class MessageServiceImpl implements MessageService {
   ...
   @Override
   public Message reply(Message message) {
        ...
        return this.send(message);
   }

   @Override
   public Message send(Message message) {
         ...
   }
}

양상

@Aspect
@Component
public class NewMessageAspect {
    ...
    @AfterReturning(value = "execution(* com.enbiso.proj.estudo.system.service.impl.MessageServiceImpl.send(..))", 
                    returning = "message")
    public void perform(Message message){
       ...
    }
}

send 메소드를 실행하려고하면 디버그 포인트가 aspect 수행에서 적중하지 않습니다.

최신 정보

몇 가지 조사를 수행했는데 send 메소드가 아래와 같이 reply 메소드에서 호출 될 때 이것이 작동하지 않는다는 것을 알았습니다.

@Autowire MessageService messageService;
...
messageService.reply(message);

그러나 messageService.send (message) 메서드를 호출하면 정상적으로 작동합니다. 그러나 reply 메쏘드가 내부적으로 send 메쏘드를 호출 할 때 aspect를 호출해서는 안 되는가?

나는 내가 무엇을 잘못했는지 전혀 모른다. 도와주세요.

해결법

  1. ==============================

    1.일을 정리해 주셔서 감사합니다. 향후 개발자를위한 정보 목적으로 만이 질문에 대한 답변을 게시하고 있습니다. SimplePojo에서 빈이 있다고 가정합니다.

    일을 정리해 주셔서 감사합니다. 향후 개발자를위한 정보 목적으로 만이 질문에 대한 답변을 게시하고 있습니다. SimplePojo에서 빈이 있다고 가정합니다.

    public class SimplePojo implements Pojo {
        public void foo() {
            this.bar();
        }
        public void bar() {
            ...
        }
    }
    

    foo () 메서드를 호출하면 메서드 bar ()가 다시 호출됩니다. 메소드 foo ()가 AOP 프록시에서 호출되었다고 생각해도 bar ()의 내부 호출은 AOP 프록시에서 다루지 않습니다.

    해결책

    메소드를 호출하려면 AopContext.currentProxy ()를 사용하십시오. 불행히도 이것은 논리와 AOP를 연결합니다.

    public void foo() {
       ((Pojo) AopContext.currentProxy()).bar();
    }
    

    참고:

    http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html#aop-understanding-aop-proxies

  2. ==============================

    2.자체 호출시 Spring AOP의 제한 사항을 실행 중입니다. 기본적으로 AopContext.currentProxy (), 다른 빈으로 리팩토링 코드를 사용하거나 완전한 ApsectJ 직조를 사용하여이 문제를 해결할 수 있습니다.

    자체 호출시 Spring AOP의 제한 사항을 실행 중입니다. 기본적으로 AopContext.currentProxy (), 다른 빈으로 리팩토링 코드를 사용하거나 완전한 ApsectJ 직조를 사용하여이 문제를 해결할 수 있습니다.

    여기 설명 및 해결 방법을 참조하십시오. http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html#aop-understanding-aop-proxies

  3. ==============================

    3.나는 문제가 @args 조건이라고 생각한다.

    나는 문제가 @args 조건이라고 생각한다.

    Spring 문서에는 다음 내용이 나와 있습니다.

    @args - limits matching to join points (the execution of methods when using Spring AOP) where the runtime type of the actual arguments passed have annotations of the given type(s) 
    

    그러므로 @args의 매개 변수는 유형 표현식이어야합니다. 따라서 올바른 pointcut 표현식은 다음과 같습니다.

    @AfterReturning(value = "execution(* com.enbiso.proj.estudo.system.service.impl.MessageServiceImpl.send(..)) && args(com.enbiso.proj.estudo.system.service.impl.Message")
    

    또는 단순히

    @AfterReturning(value = "execution(* com.enbiso.proj.estudo.system.service.impl.MessageServiceImpl.send(com.enbiso.proj.estudo.system.service.impl.Message))")
    

    메시지 패키지가 적합하지 않은 경우이를 조정하십시오.

  4. from https://stackoverflow.com/questions/30598118/spring-aop-not-working-when-the-method-is-called-internally-within-a-bean by cc-by-sa and MIT license