🐢 꼬부기 LV.1 | 개념•기초/💧물대포(핵심개념)

어드바이스 사용해보기

서화 2026. 1. 26. 21:45

✔️바인드 변수

바인드 변수는 조인포인트의 정보를 어드바이스의 인자로 전달하기 위한 변수다.
즉, 핵심 관심사(비즈니스 메서드)의 정보를 어드바이스에서 직접 사용할 수 있게 해준다.

바인드 변수를 사용하면

  • 메서드 이름
  • 메서드 인자
  • 반환값
    등을 어드바이스에서 받아 로그로 활용할 수 있다.

개념적으로는 커맨드 객체와 매우 유사한 역할을 한다고 볼 수 있다
바인드 변수를 사용하면 코드 수정 없이도 로그 내용이 자동으로 달라지므로, 정확하고 일관된 로그 작성이 가능하다

✔️바인드 변수 사용하기

🛠️PlusLogAdvice

📌바인드 변수 사용시 인자에 JoinPoint를 사용할수 있다 

로그의 시작과 끝을 정하고 핵심관심사의 메서드명을 가져올수있고 배열도 사용 가능하다 배열을 사용하면 핵심관심에서 사용하는 메서드 인자를 가져올수 있다

import org.aspectj.lang.JoinPoint;
// AOP에서 핵심 관심사(비즈니스 메서드)의 정보를 담는 JoinPoint 임포트

public class PlusLogAdvice {
	public void printLog(JoinPoint jp) {
		// 바인드 변수인 JoinPoint를 인자로 두는 순간부터,
		// 이 어드바이스와 엮이게되는 핵심관심의 정보를 받아올수있음
		
		System.out.println("향상된 꼬부기님의 로그 시작");
        // 어드바이스 실행 시점(before라면 핵심 관심사 실행 전)
		
		String methodName = jp.getSignature().getName(); // 핵심관심사 메서드명 가져오기
		System.out.println("핵심관심 메서드명 : "+methodName);
		
		Object[] args = jp.getArgs();// 핵심 관심사 메서드에 전달된 인자들을 배열로 가져온다
		System.out.println("메서드 인자들을 받아올수있음");
		for(Object arg:args) { // 향상된 포문 사용하여 값 출력하기
			System.out.println(arg);
		}
		
		System.out.println("향상된 꼬부기님의 로그 끝"); 
        // 어드바이스 종료 시점 (after라면 핵심 관심사 이후)

	}
}

콘솔 출력 확인

🛠️AroundAdvice

📌어라운드 어드바이스에서는 인자로 ProceedingJoinPoint를 사용할수 있다

프로시딩 조인포인트는 조인포인트를 상속한 것이다

주로 성능을 측정할때 사용하고 스프링에서 제공하는 스탑워치를 사용하여 비즈니스메서드의 수행시간을 보여줌으로서 성능 개선을 보여줄수있다

public class AroundAdvice {
	public Object around(ProceedingJoinPoint pjp) throws Throwable {
		
		String methodName = pjp.getSignature().getName(); //핵심관심사 메서드 이름 가져오기
		System.out.println("현재 수행중인 비즈니스 메서드 : "+methodName);
		
		StopWatch sw = new StopWatch(); // 스프링에서 제공하는 스탑워치 사용선언
		sw.start(); // 스탑워치 시작
		Object returnObj = pjp.proceed();//비즈니스 메서드 수행
		sw.stop();//스탑워치 끝
		
		System.out.println("수행에 걸린시간 : "+sw.getTotalTimeMillis()+"ms");
		// 비즈니스 메서드 수행에 걸린 전체 시간(ms) 출력
		
		return returnObj;// 비즈니스 메서드의 반환값을 그대로 다시 반환
	}
  }

콘솔 출력 화면

🛠️AfterReturningAdvice

📌에프터리터닝어드바이스는 인자로 조인포인트와 오브젝트를 사용할수 있다

비즈니스 메서드 수행결과를 로그로 표시하고 보드에서는 반환값이 있는 메서드가 2개로 보통 Read와Update에 주로 사용한다

바인드 변수가 추가되면 애스펙트 설정시 인자가 하나 더 있다고 알려줘야한다

<aop:aspect ref="ara">
  	<aop:after-returning method="printLog" pointcut-ref="bPointcut" returning="returnObj" />
 </aop:aspect>

보드에서 출력될때는 게시글 관련 메서드가 실행된것이고 멤버에서 출력될때는 멤버롤에 따라 로그인한 사용자가 누구인지 로그로 확인할수 있다

public class AfterReturningAdvice {
		public void printLog(JoinPoint jp,Object returnObj) {
			//인자로 조인포인트와 오브젝트를 사용함
			System.out.println("====꼬부기===="); // 비즈니스 메서드가 정상 종료되고 반환값이 나온 직후 실행
			
			if(returnObj instanceof BoardDTO) { //반환하는값이 게시글이라면
				System.out.println("게시글 관련 메서드");//게시글 관련메서드 출력
			}
			else if(returnObj instanceof MemberDTO) { // 반환하는 값이 멤버라면
				MemberDTO member = (MemberDTO)returnObj; // 오브젝트를 다운 캐스팅 하여 멤버로 변경
				if(member.getMrole().equals("ADMIN")) {//로그인 한사람이 관리자라면
					System.out.println(">>> 관리자 로그인 <<<");
				}
				else { // 일반 사용자라면
					System.out.println(">>> 일반 로그인 <<<");
				}
			}
			else { //게시글 전체출력이라면
				System.out.println("SELECTALL 관련 메서드");
			}
			
			System.out.println("====거북왕====");
	
		}
}

멤버에 따로 코드를 만들지 않았는데 멤버도 실행되는 이유는 xml설정에서 경로를 패키지로 지정했기때문이다

 <context:component-scan base-package="com.example.biz" />

보드클라이언트 콘솔 출력 확인

멤버클라이언트 콘솔 출력 확인

🛠️ AfterThrowing

📌예외발생시 출력되는 어드바이스로 인자로 조인포인트와 익셉션을 사용한다

에프터리터닝과 마찬가지로 에스펙트 설정시 인자가 하나 더 있다고 알려줘야한다

개발중에 사용하고 배포할때는 제거하고 배포한다 해결코드는 에러 발생 지점에 넣기때문에 로그를 처리한 본인이 적지 않을수도 있다 즉 에러 기록용으로 작성한다

public class AfterThrowingAdvice {
	public void printLog(JoinPoint jp, Exception exceptObj) {
		//인자로 조인포인트와 익셉션을 사용한다
		System.out.println("예외발생시 에러타입 출력"); 
		if(exceptObj instanceof NullPointerException) {
			System.out.println("몇월 몇일 확인된 예외");//언제 확인된 예외인지
			System.out.println("누구님이 조치함");//누가 고쳤는지도 로그로 남길수 있음
		}
		else {
			System.out.println("미확인 예외 발생!!!"); //고쳐지지 않은 예외출력
		}
	}
}

콘솔 출력 확인