코딩항해기

[Spring] AOP의 JoinPoint 본문

Spring

[Spring] AOP의 JoinPoint

miniBcake 2024. 10. 15. 16:19

 

 

JoinPoint

(import org.aspectj.lang.JoinPoint;)

 

어드바이스 메소드를 의미있게 구현하려면 클라이언트가 호출한 비즈니스 메소드의 정보가 필요하다. 예를들면 예외가 발생했을 때 예외발생한 메소드의 이름이 뭔지 등을 기록할 필요가 있을 수 있고, 해당 정보에 대한 로그를 띄우기 위해 사용할 수도 있다.

Signature getSignature() 클라이언트가 호출한 메소드의 시그니처(리턴타입, 이름, 매개변수) 정보가 저장된 Signature 객체 리턴
Object getTarget() 클라이언트가 호출한 비즈니스 메소드를 포함하는 비즈니스 객체 리턴
Object[] getArgs() 클라이언트가 메소드를 호출할 때 넘겨준 인자 목록을 Object 배열 로 리턴

 

Signature API

String getName() 클라이언트가 호출한 메소드 이름 리턴
String toLongString() 클라이언트가 호출한 메소드의 리턴타입, 이름, 매개변수(시그니처)를 패키지 경로까지 포함 하여 리턴
String toShortString() 클라이언트가 호출한 메소드 시그니처를 축약한 문자열로 리턴

 

사용

 

JoinPoint를 어드바이스 메소드 매개변수로 선언해야한다. 이때 인자는 스프링 컨테이너가 넘겨준다. 

이때 Around 어드바이스만 다른 어드바이스와 약간 다른데, ProceedingJoinPoint 객체를 인자로 선언해야한다.(proceed() 등이 추가로 구현되어있음) ProceedingJoinPoint 는 JoinPoint를 상속받는다.

 

@Slf4j
public class LogAdvice {
    public void insertLogName(JoinPoint jp){
        //jp는 바인드 변수

        //현재 이 Advice와 연결된 JoinPoint와 메서드명 == 포인트컷의 메서드명
        //jp.getSignature().getName() => 메서드 이름

        //현재 이 Advice와 연결된 조인 JoinPoint의 매개변수 정보 == 포인트컷의 매개변수 정보
        //jp.getArgs() (반환타입 배열)

        log.info("AOP{}: '{}'님이 DB에 글을 등록했습니다.", jp.getSignature().getName(), ((BoardDTO)jp.getArgs()[0]).getWriter());
    }
}

 

	<aop:config>
		<aop:pointcut expression="execution(* com.koreait.app.biz..*Impl.selet*(..))" id="logPointcut" />
		<!--설정-->
		<aop:aspect ref="la">
			<aop:after method="insertLogName" pointcut-ref="logPointcut"/>
		</aop:aspect>
	</aop:config>

 

 

반환 값을 받아오는 경우도 있는데 관리자를 트래킹하거나 특수한 계정을 트래킹할 때 사용한다.

public class CheckAdvice {
	public void check(Object returnObj) {
		if(returnObj instanceof MemberDTO) {
			MemberDTO memberDTO = (MemberDTO)returnObj;
			if(memberDTO.getRole().equals("USER")) {
				System.out.println("회원이 로그인했습니다.");
			}
			else {
				System.out.println("관리자가 로그인했습니다.");
			}
		}
	}
}
	<aop:config>
		<aop:pointcut expression="execution(* com.koreait.app.biz..*Impl.select*(..))" id="bPointcut" />	
		<aop:aspect ref="ta">
			<aop:after-returning pointcut-ref="cPointcut" method="print" />
		</aop:aspect>
	</aop:config>