AOP 프로그래밍
(Aspect Oriented Programming)
spring-aop API
aspectjweaver
참고)
finally 구문을 사용할 경우 return 뒤에 실행함.
java.lang.reflect.Proxy
invocationHandler
-인터페이스를 통한 프록시 / 인터페이스 정의가 필수
// 공통 부분 정의
package exam02;
public class CalculatorHandler implements InvocationHandler {
private Object obj;
public CalculatorHandler(Object obj) {
this.obj = obj;
}
/**
*
* @param method : 호출한 메서드의 정보
* 동적 메서드 호출 method.invoke(...)
* args : 메서드 호출시 넘겨준 값 (인수)
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long stime = System.nanoTime();
try {
Object result = method.invoke(obj, args); // 핵심 기능 proxy 가 대신 수행
return result;
} finally {
long etime = System.nanoTime();
System.out.printf("걸린 시간:%d%n", etime - stime);
}
}
}
// test
public class Ex02 {
@Test
void test1() {
Object obj = Proxy.newProxyInstance(
Calculator.class.getClassLoader(),
new Class[] { Calculator.class },
new CalculatorHandler(new RecCalculator())
);
Calculator cal = (Calculator) obj;
long result = cal.factorial(10L);
System.out.println(result);
}
}
-Aspect oriented Programming: 관점 지향 프로그래밍
aspectjweaver - 구현체
관점: 개발자의 공통적인 관심사항
공통 기능, 핵심 기능 분리 기술
공통 기능 - 스프링이 대신 수행
핵심 기능 - 개발자 정의
-스프링이 관리하는 객체만 관리 기능을 제공
-스프링 컨테이너에 있는 객체만 적용 가능
-공통 기능이 정의된 클래스
- execution 명시자 - Ant 패턴
-공통 기능이 적용될 패키지 범위, 메서드 패턴
3) 공통 기능을 수행할 메서드 위에
@Before
: 메서드가 호출되기 전 공통 기능
@After
: 메서드가 호출된 후 공통 기능
@AfterReturing
: 반환 값을 내보낸 후 공통 기능
@AfterThrowing
: 예외가 발생한 후 공통 기능
@Around
: 메서드 호출 전, 호출 후 공통 기능
ProceedingJoinPoint
Object Proceed() : 핵심 기능 대신 실행
Signature getSignature() : 호출한 메서드 정보
-getTarget() : 실제 메서드를 호출한 객체(RecCalculator..)
-Object[] getArgs() - 인수목록
Signature
String getName()
String toLongString()
String toShortString()
.* -> exam01.* -> exam01 패키지의 하위 클래스 / exam01.RecCalculator
..* -> exam01..* -> exam01 패키지를 포함한 하위 패키지 포함 모든 클래스
예) exam01.sub.RecCalculator, exam01.sub1.sub2.RecCalculator
* aopex.*.*()
모든 반환값
aopex.* -> aopex 패키지 모든 하위 클래스
aopex.*.* -> aopex 패키지 모든 하위 클래스의 모든 메서드
aopex.*.*() -> aopex 패키지 모든 하위 클래스의 매개변수가 없는 모든 메서드
* aopex.*()
* aopex..*.*(..) -> 모든 반환값에 aopex 패키지를 포함한 하위 패키지 포함 모든 클래스 모든 메서드
* aopex..*(..)
* get*(*) -> get으로 시작하는 매개변수가 1개 짜리 메서드
* get*(*,*) -> get으로 시작하는 매개변수가 2개 짜리 메서드
* read*(Interger, ..) -> 메서드명이 read로 시작하고 첫 번째 매개변수는 Integer로 고정, 두 번째 부터는 0개 이상 매개 변수
// 메서드가 호출될 범위를 설정해줌
//@EnableAspectJAutoProxy (proxyTargetClass = true) 사용시
proxy가 RecCalculator 하위 클래스가 됨
ProxyCache -> ProxyCalculator (순서가 반드시 지켜져야 함)
-> 프록시의 적용 순서, 숫자가 작은 순서부터 적용
@Around("CommonPointcut.publicTarget()")
공통 포인트컷을 생성해서 사용 가능