강좌/Spring 3.0

013. AOP - 기초 완성

여름나라겨울이야기 2013. 1. 23. 15:32
728x90

이번 시간에는 Before 어드바이스와 After 어드바이스를 살펴보도록 하겠습니다.

 

그런데 이미 AOP 이전 강좌에서 Before 어드바이스를 살펴봤네요.

그래서 생략..

 

다만 기억할 것은 Before 어드바이스는 해당 Jointpoint 메서드 실행 전에 실행 된다는 사실을 기억해 주시면 되겠습니다.

 

그럼 After 어드바이스는?  당연히 해당 Joinpoint 메서드 실행 후에 실행되겠군요.

소스로 이야기해 봅시다.  기존 aop003 패키지를 복사해서 aop004 패키지를 만들었습니다.

 

변할 곳은 짐작이 되시나요?

네 딱 두 곳입니다.  Advice 를 만드는 클래스와 Spring AOP 설정이죠.

 

변경된 MyAspect.java 입니다.

 

package aop004;

import org.aspectj.lang.JoinPoint;

public class MyAspect {
 public void before(JoinPoint joinPoint){
  System.out.println("얼굴 인식 확인: 문을 개방하라");
  //System.out.println("열쇠로 문을 열고 집에 들어간다.");
 }
 
 public void lockDoor(JoinPoint joinPoint){
  System.out.println("주인님 나갔다: 어이 문 잠궈!!!");
  //System.out.println("자물쇠를 잠그고 집을 나선다.");
 }
 
}

 

Spring 설정 파일 expert.xml 입니다.

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
 <aop:aspectj-autoproxy /> 
 
 <bean id="myAspect" class="aop004.MyAspect" />
 <bean id="boy" class="aop004.Boy" />
 <bean id="girl" class="aop004.Girl" />
 
 <aop:config>
  <aop:aspect ref="myAspect">   
   <aop:before method="before" pointcut="execution(* housework())" />
   <aop:after method="lockDoor" pointcut="execution(* housework())" />
  </aop:aspect>
 </aop:config>
</beans>

 

보시는 것처럼 별반 어려울 것이 없습니다.  <aop:after ..> 캬.. 이름 직관적이지 않습니까?

아 그리고 Start.java 에서 당연히 xml 경로는 맞추어 주셨죠?

 

new FileSystemXmlApplicationContext("/src/main/java/aop004/expert.xml")

 

그럼 실행 결과는...

 

 

멋집니다.  혹시나 @ 애너테이션 기반이 좋은 분들을 위해서 aop005 도 만들어 봅시다.

 

MyAspect.java @ 애너테이션 기반

 

package aop005;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

 

@Aspect
public class MyAspect {
 @Before("execution(* housework())")
 public void before(JoinPoint joinPoint){
  System.out.println("얼굴 인식 확인: 문을 개방하라");
  //System.out.println("열쇠로 문을 열고 집에 들어간다.");
 }
 
 @After("execution(* housework())")
 public void lockDoor(JoinPoint joinPoint){
  System.out.println("주인님 나갔다: 어이 문 잠궈!!!");
  //System.out.println("자물쇠를 잠그고 집을 나선다.");
 } 
}

 

expert.xml @ 애너테이션 기반

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
 <aop:aspectj-autoproxy /> 
 
 <bean id="myAspect" class="aop005.MyAspect" />
 <bean id="boy" class="aop005.Boy" />
 <bean id="girl" class="aop005.Girl" />
</beans>

 

역시 Start.java 에서 expert.xml 경로 변경 잊지 마시고, 저장 후 실행하시면 같은 결과를 확인하실 수 있습니다.

 

그리고 lockDoor 메서드의 파라미터는 JoinPoint 객체 하나인데요.  원하시면 대상 메서드 homework() 의 리턴값도 파라미터화 해서 받으실 수 있습니다.  그렇다고 하는 것은 호출에 대한 반납값을 조작하는 것도 가능할 것 같다는... 자세한 건 책을 보세요. ^^

 

자 그럼 마무리 하기 전에..

 

XML 기반의 설정 파일을 잠시 보면 눈에 거슬리는게 있습니다.

마찬가지로 애너테이션 기반에서도 눈에 거슬리는게 있습니다.

제가 거슬리라고 빨간색으로 이미 칠해 두었습니다.

 

저의 복선을 이전에 알아채셨나요?  바로 바로 중복이라는 거죠.

프로그램 세계에서 중복은 죄악이자 리팩토링(?)의 대상입니다.  리팩토링 해야겠죠.

 

XML 설정 파일 기반이라면 expert.xml 만 변경해 주시면 됩니다.

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
 <aop:aspectj-autoproxy /> 
 
 <bean id="myAspect" class="aop004.MyAspect" />
 <bean id="boy" class="aop004.Boy" />
 <bean id="girl" class="aop004.Girl" />
 
 <aop:config>
  <aop:pointcut expression="execution(* housework())" id="iampc"/>
  
  <aop:aspect ref="myAspect">   
   <aop:before method="before" pointcut-ref="iampc" />
   <aop:after method="lockDoor" pointcut-ref="iampc" />
  </aop:aspect>
 </aop:config>
</beans>

 

@ 애너테이션 기반이라면 MyAspect.java 만 변경해 주시면 됩니다.

 

package aop005;

 

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

 

@Aspect
public class MyAspect {
 @Pointcut("execution(* housework())")
 private void iampc() {
  // 여긴 무엇을 작성해도 의미가 없어요.
 }

 
 @Before("iampc()")
 public void before(JoinPoint joinPoint){
  System.out.println("얼굴 인식 확인: 문을 개방하라");
  //System.out.println("열쇠로 문을 열고 집에 들어간다.");
 }
 
 @After("iampc()")
 public void lockDoor(JoinPoint joinPoint){
  System.out.println("주인님 나갔다: 어이 문 잠궈!!!");
  //System.out.println("자물쇠를 잠그고 집을 나선다.");
 } 
}

 

오늘의 소스는 여기까지 입니다.

 

자 그리고 설명하지 않은 것들이 있는데요.

 

Before, After 외에도 3 가지가 더 있다고 했는데 언제 언제 일까요? (역시 잠깐 생각하시라고 밑에 숨겨놨습니다. 마우스 드래그 하는 수고는 생각해 보신 후에.. ^^)

 

AfterRetruning, AfterThrowing, Around 가 있습니다. 이름에서부터 딱 느낌이 오시죠!!!

Around 만 빼고는 대동 소이합니다.

이쯤 되면 제가 무슨 이야기 하려는지 아시겠죠.

책.. 다른 강좌.. ^^;

 

스프링 본격적인 학습을 위한 DI 기초와 AOP 기초에 대해서 살펴봤습니다.

이제 곧바로 책을 향해, 구글링을 향해 돌진???

 

에이 스프링 3대 핵심 기술이라니깐요.

강좌 하나만 더 참아보세요.

 

스프링 3대 핵심 기술 기억하세요?

 

DI

AOP

추상화

 

그럼 다음 강좌에 추상화로 만나뵙죠.

 

샬롬....

반응형