Java/스프링 AOP

스프링 AOP - 내부호출 문제

ta_chan 2023. 9. 17. 14:09
package com.example.demo.exam.internalcall;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class CallServiceV0 {
    public void external(){
        log.info("call external");
        internal(); // 내부 메서드 호출(this.internal())
    }

    public void internal(){
        log.info("call internal");
    }
}

위같은 경우처럼 external() 메서드 내부에 internal(); 메서드를 호출하게 되면 internal메서드는 내부에서 external 내부에서 호출되기 때문에 프록시객체가 생성되지 않는다.

aop=void com.example.demo.exam.internalcall.CallServiceV0.external()
call external
call internal
target=class com.example.demo.exam.internalcall.CallServiceV0$$EnhancerBySpringCGLIB$$e7d7dbab

 

이 경우에는 internal() 메서드 자체를 따로 클래스로 빼서 호출하면 해결된다.

 

package com.example.demo.exam.internalcall;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class InternalService {

    public void internal(){
        log.info("call internal");
    }
}
package com.example.demo.exam.internalcall;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@RequiredArgsConstructor
public class CallServiceV3 {
    private final InternalService internalService;
    public void external(){
        log.info("call external");
        internalService.internal();
    }
}

이렇게 되면 원하는대로 프록시가 2번 호출이 된다.

aop=void com.example.demo.exam.internalcall.CallServiceV3.external()
call external
aop=void com.example.demo.exam.internalcall.InternalService.internal()
call internal