티스토리 뷰


이번에 살펴볼 내용은 다시 AOP 입니다.


간단하면서도 유용하게 쓰일만한 내용인 것 같아서 메모용, 참고용 으로 포스팅을 해봅니다.


먼저, 간단하게 사용자 아이디를 헤더에서 검색하는 AOP를 작성했습니다.

import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@Aspect
public class UserCheckAOP {
	
	@Around("@annotation(com.test.api.member.aop.UserCheck)")
	public Object userLoginCheck(ProceedingJoinPoint jp) throws Throwable {
		
		// 애플리케이션에서 Request 객체를 읽어옴
		HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		
		String userId = "";
		
		if (req != null) {
			userId = req.getHeader("userId");
		}
		
		if ( userId == null || userId.equals("") ) {
			System.out.println("시스템 에러");
		}
		
		Object resultObj = jp.proceed(new Object[] { userId });
		return resultObj;
	}
}


Around advice 에서 HttpServletRequest 를 ProceedingJoinPoint에서 파라미터 객체로 읽어오지 않은 이유는

타겟 메소드에서 HttpServletRequest 객체를 파라미터로 갖지 않은 상태로 두고 싶어서 입니다.


위처럼 ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); 를 이용해서 읽어오면, 타겟 메소드(포인트 컷으로 지정하는)에 request 객체를 파라미터로 가지지 않아도 에러가 발생하지 않습니다.


이것은 여기서 중점이 아니니 넘어가고, 정말 간단합니다. 


미리 Around advice에서 타겟 메소드 실행 전후를 ProceedingJoinpoint 객체의 proceed() 메소드로 구분해서 처리할 수 있는 것은 이전에 AOP 포스팅을 보시면 알 수 있으니 참고해주세요.


저는 지금 API 형태의 프로젝트를 진행하고 있기 때문에, 모든 메소드가 리턴 값을 가집니다.

proceed() 메소드는 타겟 메소드 실행 후 리턴 값도 가져올 수 있죠.


하지만 오늘 내용은 이전 내용입니다. 

proceed() 이전에 미리 데이터를 처리하여, 해당 처리한 결과를 타겟 메소드에 보내고 싶은 것이죠.


어렵지 않습니다.  proceed() 메소드는 오버라이드로 Object 배열을 파라미터로 가지는 메소드가 있습니다.

proceed(Object[] args) 형태로 말이죠.


위 소스에서 보면 헤더에서 userId 값을 가져오고, 대충 빈값인지 널값인지 체크하고, 존재하면 타겟메소드로 보내려고 하는 것입니다.


그래서 jp.proceed(new Object[] { userId}) 의 형태로 전달을 하는 것이죠.

이 때, 중요한 점은 타겟 메소드에서 @RequestParam을 받는 것처럼 해당 파라미터를 가지고 있어여 합니다.


그래야 값이 전달이 되겠죠?


그리고 전달하는 파라미터 갯수와, 타겟메소드에서 받을 파라미터 갯수가 온전히 일치해야 합니다.

타겟메소드에서는 파라미터 갯수가 3개 인데.. 여기서는 1개만 전달한다 그러면 에러가 발생합니다.


참고해 주시고, 위에서 처럼 간단히 스트링 값 이외에서, 헤더값 이외에서 Request 객체를 통해 전달되는 값들을 처리할 수 있으며, 여러개의 객체도 전달 할 수 있습니다^^


P.S 위에 포인트 컷은 애노테이션을 활용한 것이라, 애노테이션 객체를 포인트 컷으로 정의한 것입니다.


감사합니다.

댓글