프로그래밍

[Spring] day67 : AOP 예제(+바인드 변수) 본문

자바/Spring

[Spring] day67 : AOP 예제(+바인드 변수)

시케 2023. 8. 16. 20:41
728x90
반응형

2023.08.11.금

AOP 예제

포인트 컷을 여러 개 등록할 수 있으며 해당 경우가 흔하다

 

주로 CUD는 DB에 직접적인 변화를 주기 때문에

데이터에 대한 확실한 검증이 필요하다

상대적으로 보안, 우효성 검사, 트랜잭션, ... 등이 많이 필요로 한다

 

반면에 R은 DB에 변화가 없다

보려는 데이터에 접근할 수 있는 권한이 있는지만 확인하면 되는 경우가 다수이다
∴ 상대적으로 공통 로직이 적게 필요하다

 

일부 포인트컷에만 어드바이스(횡단관심, 공통로직)가 동작할 수 있는 설정이 가능하다

 

어드바이스 동작 설정 메서드

before: 비즈니스 메서드 전에 어드바이스가 호출됨

after: 비즈니스 메서드 후에 어드바이스가 호출됨
after-returning: 비즈니스 메서드 OUTPUT반환후에 어드바이스가 호출됨
after-throwing: 비즈니스 메서드 오류발생후에 어드바이스가 호출됨
around: 비즈니스 메서드를 수행하기 전,후에 호출됨
※ 비즈니스 메서드 수행하기 전에 1번 + 비즈니스 메서드 수행하기 후에 1번 총 2번 불러와지는 것이 아니다!
 around가 진행되는 동안에 비즈니스 메서드가 내부에서 호출되는 것

∴ 실행할 비즈니스 메서드를 인자로 받아와야 한다(JointPoint)

 

package com.spring.biz.common;

@Service
@Aspect
public class LogAdvice {
	@Before("PointCutCommon.aPointcut()")
	public void beforeLog() {
		System.out.println("횡단관심: 비즈니스 메서드 수행 전에 호출됨");
	}
	
	@After("PointCutCommon.aPointcut()")
	public void afterLog() {
		System.out.println("[횡단관심]");
		System.out.println("     비즈니스 메서드 수행 후에 호출됨");
		System.out.println();
	}
	
	@AfterReturning(pointcut="PointCutCommon.bPointcut()", returning="returnObj")
	public void afterReturningLog(JoinPoint jp, Object returnObj) {
		String methodName=jp.getSignature().getName();
		System.out.println("횡단관심 : "+methodName+"의 반환 이후의 로그");
		if(returnObj instanceof MemberVO) {
			MemberVO mVO=(MemberVO)returnObj;
			if(mVO.getRole().equals("ADMIN")) {
				System.out.println("[관리자 입장]");
			}
			else {
				System.out.println("[사용자 입장]");
			}
		}
		else {
			System.out.println("[데이터 열람]");
		}
	}
	
    // 예외발생시 trycatch 되어있으면 어드바이스 호출되지 않음
	@AfterThrowing(pointcut="PointCutCommon.aPointcut()", throwing="exceptObj")
	public void afterThrowingPrintLog(JoinPoint jp, Exception exceptObj) {
		String methodName = jp.getSignature().getName();
		System.out.println("횡단 관심 : "+methodName+"에서 예외가 발생해서 출력되는 로그");
		System.out.println("예외 메세지 : "+exceptObj.getMessage());
	}
	
	@Around("PointCutCommon.aPointcut()")
	public Object aroundPrintLog(ProceedingJoinPoint pjp) throws Throwable {
		System.out.println("around 로그 전");
		StopWatch sw=new StopWatch();
		sw.start();
		Object obj=pjp.proceed();
		sw.stop();
		String methodName=pjp.getSignature().getName();
		System.out.println(methodName+" 메서드를 수행하는데에 소요한 시간은 "+sw.getTotalTimeMillis()+"초입니다.");
		System.out.println("around 로그 후");
		return obj;
	}
}

 

위의 코드에서 보면 해당 로그 메서드들이 어느 객체를 혹은 어느 비즈니스 메서드가 인자로 들어올지 모르는 상태이다

이런 경우

객체의 경우에는 최상위 객체인 Object를

비즈니스 메서드의 경우에는 JoinPoint를 인자로 선언 후 바인딩한다

 

바인딩 변수

자동으로 바인딩되는 변수이다

OOP(객체 지향 프로그래밍)의 다형성을 통해 바인딩 기법을 구현해낼 수 있다

 

우리가 사용한 Object, ProceedingJoinPoint 모두 바인딩 변수이다

실제로 Object에 들어있는 객체는  memberVO 혹은 BoardVO이지만

무엇이 인자값으로 받아올지 모르니 포장을 Object 객체로 설정하는 것이다

 

https://github.com/jihyean/Spring/tree/main/day67

 

728x90
반응형
Comments