티스토리 뷰

생활코딩/Spring

스프링 배우기 - AOP 2

우봉이 2014. 3. 19. 11:25

AOP 를 이용한 예제 공부는 앞에서 공부해보았다.

전체적인 이해를 돕기 위해서 기존의 예제 프로젝트인 게시판에 AOP 기능을 추가해서 흐름을 파악해 보려고 한다.

게시판에서 로그인과 글쓰기 과정에서

 글쓰기 상태에서 로그인이 되어 있지 않을 때, 로그인 창을 호출하고 글쓰기에서 로그인이 요청 되었을 때는, 로그인 후 바로 글쓰기 창을 보여주는 시나리오이다.

여기서 로그인 처리 외에, 로그인 창을 구분하여 사용자에게 보여줘야 할 View를 변경하는 부가적인 부분을 AOP로 처리해보자.

먼저, 앞에서 정리한 대로 AOP 사용을 위한 라이브러리를 추가한다. ( AspectJWeaver 1.7.4, cglib 2.2.2 )

-  AOP를 지정할 본래 메소드

@RequestMapping("/writeForm.ktds")
	public ModelAndView writeForm(HttpServletRequest req) {
		
		mav = new ModelAndView();
		mav.setViewName("writeForm");
		return mav;
	}

-  AOP의 Around Advice 소스코드

	@Pointcut("execution(* com.ktds.bbs.controller.BBS_Controller.*writeForm(..))")
	public void writeFormLogin() {
	}
	
	@Around("writeFormLogin()")
	public ModelAndView writeFormAspect(ProceedingJoinPoint joinPoint)
			throws Throwable {
		HttpServletRequest req = null;
		ModelAndView mav = new ModelAndView();
		Object[] ob = joinPoint.getArgs();
		if (ob[0] instanceof HttpServletRequest) {
			req = (HttpServletRequest) ob[0];
		}

		HttpSession session = req.getSession();

		if (session.getAttribute("id") == null) {
			session.setAttribute("logined", "no");
			mav.setViewName("LoginPage");
		} else {
			mav = (ModelAndView) joinPoint.proceed();
		}
		return mav;
	}

 Around 어드바이스에서 joinPoint.proceed()를 만나기 전까지는 Before 어드바이스와 같은 상태로 위 소스가 실행 된다.

매개변수는 위와 같이 joinPoint.getArgs() 를 통해, 본래 메소드가 받은 매개 변수를 받아 올 수 있고, Object 이므로 형 변환을 해줘야 한다.

해석해보면, 글쓰기를 요청하여서 글쓰기 Form 을 반환 해줘야 하는데, 여기서 로그인이 된 상태인지 안 된 상태인지 체크하는 것이다. 로그인이 안되어 있으면, 로그인 페이지로 이동하고 로그인이 되어 있으면, Form 으로 이동하면 된다.

본래 메소드는 글쓰기 Form 으로 반환하는 부분만 구현 되어 있지만, AOP를 통해 session에 로그인 처리 후 등록 된 id 가 있는 지 확인하여, 로그인이 안되어 있으면 LoginPage로 View를 지정하고, 로그인이 되어 있으면, JoinPoint.proceed()를 통해 본래의 메소드 소스 코드인 writeForm을 View 로 지정한다.


Around 에서 joinPoint.proceed() 에 대한 시점 이 중요하다.

proceed()를 기준으로 위의 소스는 before, 아래의 소스는 afterThrowing 로 구분 지어질 수 있다.

proceed() 의 리턴 값은 Object 이다. 이는 Aspect 로 연결된 Original Method 의 리턴 값을 받을 수 있다. ( 형 변환 ) 

또 하나 중요한 점은 Advice ( Aspect Method ) 의 리턴 타입이 Original Method 의 리턴 값과 형이 맞아야 한다.




댓글