-
스프링4.0 - AOP : @Aspect 기반웹프로그래밍/spring 2018. 7. 16. 21:10
XML 스키마 설정 대신에 @Aspect 어노테이션을 클래스에 적용한다.
1. Before Advice
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class ArticleCacheAspect {
private Map<Integer, Article> cache =new HashMap<Integer, Article>();
@Around("execution(public * *..ReadArticleService.*(..))")
public Article cache(ProceedingJoinPoint joinPoint) throws Throwable {
Integer id = (Integer) joinPoint.getArgs()[0];
Article article = cache.get(id);
if(article != null) {
System.out.println("[ACA] 캐시에서 Article["+id+"] 구함");
return article;
}
Article ret = (Article) joinPoint.proceed();
if(ret != null) {
cache.put(id, ret);
System.out.println("[ACA] 캐시에서 Article["+id+"] 추가함");
}
return ret;
}
}
2. After Returning Advice
Advice 대상 객체가 리턴한 값을 사용하고 싶다면
@AfterReturning에 returning 속성을 넣고
구현 메서드의 파라미터로 세팅하면 그 리턴 값을 전달 받을 수 있다.
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
@AfterReturning(pointcut="대상 객체의 클래스 경로" returning="ret")
public void afterReturning(Object ret) {
//공통기능
}
만약 리턴 값이 특정 객체 타입인 경우도 가능
@AfterReturning(pointcut="대상 객체의 클래스 경로" returning="ret")
public void afterReturning(Article ret) {
//공통기능
}
대상 객체의 정보가 필요한 경우
@AfterReturning(pointcut="대상 객체의 클래스 경로" returning="ret")
public void afterReturning(JoinPoint joinPoint, Object ret) {
//공통기능
}
3.After Throwing Advice
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class LoggingAspect{
@AfterThrowing("경로")
public void afterThrowing() {
//공통기능
}
대상 객체의 메서드가 발생시킨 익셉션 객체에 접근하려면 @AfterThrowing에 throwing 속성을 추가한다.
그리고 Advice 구현 메서드에 파라미터를 추가한다.
@AfterThrowing(pointcut="경로" throwing="ex")
public void afterThrowing(Throwable ex) {
//공통기능
}
Throwable이나 Exception 이외에 특정 타입의 익셉션을 넣어서 익셉션 발생을 특정할 수도 있다.
@AfterThrowing(pointcut="경로" throwing="ex")
public void afterThrowing(ArticleNotFoundException ex) {
//공통기능
}
대상 객체의 정보가 필요한 경우
@AfterThrowing(pointcut="경로" throwing="ex")
public void afterThrowing(JoinPoint joinPoint, Exception ex) {
//공통기능
}
4.After Advice
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class LoggingAspect {
@After("경로")
public void afterFinally() {
//공통기능
}
대상 객체의 정보가 필요한 경우
@After("경로")
public void afterFinally(JoinPoint joinPoint) {
//공통기능
}
5.Around Advice
Around Advice구현 메서드는 org.aspectj.lang.ProceedingJoinPoint 타입을 첫 번째 파라미터로 지정해야 한다. 아니면 익셉션 발생
ProceedingJoinPoint의 proceed()로 프록시 대상 객체의 실제 메서드를 호출 하므로,
joinpoint.proceed() 전, 후에 공통 기능을 구현한다.
import java.util.HashMap;
import java.util.Map;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import spring.chap06.board.Article;
@Aspect
public class ArticleCacheAspect {
private Map<Integer, Article> cache =new HashMap<Integer, Article>();
@Around("execution(public * *..ReadArticleService.*(..))")
public Article cache(ProceedingJoinPoint joinPoint) throws Throwable {
Integer id = (Integer) joinPoint.getArgs()[0];
Article article = cache.get(id);
if(article != null) {
System.out.println("[ACA] 캐시에서 Article["+id+"] 구함");
return article;
}
Article ret = (Article) joinPoint.proceed();
if(ret != null) {
cache.put(id, ret);
System.out.println("[ACA] 캐시에서 Article["+id+"] 추가함");
}
return ret;
}
}
'웹프로그래밍 > spring' 카테고리의 다른 글
스프링4.0 - @Valid / @InitBinder 검증 & 글로벌 Validator (0) 2018.07.17 스프링4.0 - Validator / Errors / BindingResult로 객체 검증 : 에러 메시지 (0) 2018.07.17 스프링4.0 - AOP 기초 (0) 2018.07.15 스프링 4.0 - DI : 의존성주입 자동 연결 (0) 2018.07.10 스프링 4.0 - DI(Dependency Injection) : 의존성 주입 - 수동 설정 (0) 2018.07.10