탑크리에듀교육센터(www.topcredu.co.kr)에서 제공하는 자료입니다. 스프링프레임워크 & 마이바티스(Spring Framework, MyBatis) 9번째 자료입니다. AOP 충고(Advice),프로그래밍적인 방법을 통한 AOP 구현(ProxyFactory 이용)에 대하여 설명한 자료이므로 참고하시면 좋을 것 같습니다^^.
1. 스프링프레임워크 & 마이바티스
(Spring Framework, MyBatis)
3-3. AOP 충고(Advice)
스프링 AOP에서 충고(Advice)는 횡단관심사 기능을 구현한 것인데 다음과 같이 분류한다.
2. Aroud Advice의 앞단 처리 부분과 Before Advice, Aroud Advice의 뒷단 처리부분과
AfterReturning Advice간 실행순서는 정해져 있지 않고 먼저 추가되는 Advice, Advisor가 먼저 실
행된다.
3-4. 프로그래밍적인 방법을 통한 AOP 구현(ProxyFactory 이용)
프로그래밍적인 방법을 통해 Spring AOP의 기본원리를 이해하자.
STS에서
1. File -> New -> Spring Starter Project
Name : demo-smallmart
Type : MAVEN
Package : onj.hello.aop
2. Core -> AOP 체크
3.
4. [SmallMartInterface.java]
package onj.hello.aop;
public interface SmallMartInterface {
public void getProducts(String productName) throws Exception;
}
[SmallMart.java]
package onj.hello.aop;
public class SmallMart implements SmallMartInterface {
public void getProducts(String productName) throws Exception {
System.out.println("[Target Method]getProduct()..." + productName);
throw new Exception("error..."); //주석으로 막고 실행해 보자.
5. }
}
[BeforeLoggingAdvice.java]
package onj.hello.aop;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class BeforeLogginAdvice implements MethodBeforeAdvice{
public void before(Method method, Object[] args, Object target) throws Throwable {
String findName = (String)args[0];
System.out.println(method.getName() + "(" + findName + "):: 사젂충고");
}
}
/**
* 사전 충고용 인터페이스
* 이메소드는 대상메소드, 그 메소드에 젂달할 인자, 대상객체에 대한 접근점 제공
* 메소드 인자에 접근 가능하므로 런타임중에 파라미터를 사용하여 충고 구현 가능
*/
public interface MethodBeforeAdvice {
void before(Method method, Object[] args, Object target) throws Throwable ;
}
[AfterLoggingAdvice.java]
package onj.hello.aop;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class AfterLoggingAdvice implements AfterReturningAdvice {
public void afterReturning(Object returnValue, Method method, Object[] args, Object
target) throws Throwable {
System.out.println(method.getName() + "(" + args[0] + ") :: 사후중고" );
}
}
/* 사후 충고(AfterReturning Advice)용 인터페이스 */
public interface AfterReturningAdvice {
void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws
Throwable;
6. }
[AroundLoggingAdvice.java]
package onj.hello.aop;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class AroundLoggingAdvice implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
String findName = (String) invocation.getArguments()[0];
String methodName = (String) invocation.getMethod().getName();
System.out.println("[주변충고]" + methodName + "(" + findName + ") 메소드 실행젂");
Object obj = invocation.proceed(); // 타켓클래스의 메소드 호출
System.out.println("[주변충고]" + methodName + "(" + findName + ") 메소드 실행후");
return obj;
}
}
/* 이전에 사전,사후 충고를 엮었는데 주변충고를 통해 둘 다를 엮을 수 있다.*/
public interface MethodInterceptor {
Object invoke(MethodInvocation invocation) throws Throwable;
}
MethodInterceptor 구현 클래스(주변충고용 클래스)는 대상 메소드의 실제 호출여부를 제어하며
proceed를 통해 호출 타겟 메소드 호출하며, 원래 메소드의 리턴을 대체가능하다.
[ThrowsLoggingAdvice.java]
package onj.hello.aop;
import org.springframework.aop.ThrowsAdvice;
public class ThrowsLoggingAdvice implements ThrowsAdvice {
public void afterThrowing(Throwable throwable) {
System.out.println("에러 발생...");
}
}
/* 예외가 발생했을 때의 행위를 정의, marker interface */
public interface ThrowsAdvice { }
7. 구현대상이 없지만 아래의 메소드중 하나를 포함해야 한다.
void afterThrowing(Throwable throwable);
void afterThrowing(Method method, Object[] args, Object target, Throwable throwable);
[DemoSmallmartApplication.java]
package onj.hello.aop;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoSmallmartApplication {
public static void main(String[] args) {
SpringApplication.run(DemoSmallmartApplication.class, args);
SmallMartInterface target = new SmallMart();
ProxyFactory pf = new ProxyFactory();
pf.addAdvice(new BeforeLoggingAdvice());
pf.addAdvice(new AfterLoggingAdvice());
pf.addAdvice(new AroundLoggingAdvice());
pf.addAdvice(new ThrowsLoggingAdvice());
pf.setTarget(target);
try {
SmallMartInterface proxy = (SmallMartInterface)pf.getProxy();
proxy.getProducts("생필품");
}
catch(Exception e) {e.printStackTrace(System.out); }
}
}
DemoSmallmartApplication 클래스에서 마우스 우측버튼 -> Run As -> Spring Boot App 또는
Java Application으로 실행 가능