* AOP 란
- AOP 공통기능( 로그, 권한체크, 인증, 예외처리, 트랜잭션)
- AOP는 비지니스로직을 구현한 코드에서 직접 호출하지 않고 AOP를 적용하면 컴파일하거나 컴파일된 클래스를 로딩하는 시점에 AOP가 적용된다.
* AOP 용어
관점(Aspect)
공통적으로 적용될 기능을 의미, 횡단 관심사의 기능이라 할수 있으며 한개 이상의 포인트컷과 어드바이스의 조합으로 만들어짐
어드바이스(Advice)
관점의 구현체로 조인포인트에 삽입되어 동작하는 것을 의미함. 스프링에서 사용하는 어드바이스는 동작하는 시점에 따라 다섯 종류로 구분됨
조인포인트(Joinpoint)
어드바이스를 적용하는 지점을 의미. 스프링에서 조인포인트는 항상 메소드 실행 단계만 가능함
포인트컷(Pointcut)
어드바이스를 적용할 조인포인트를 선별하는 과정이나 그 기능을 정의한 모듈을 의미. 정규표현식이나 AspectJ의 문법을 이용해서 어떤 조인포인트를 사용할지 결정
타켓(Target)
어드바이스를 받을 대상을 의미
위빙(Weaving)
어드바이스를 적용하는 것을 의미. 즉, 공통 코드를 원하는 대상에 삽입하는 것을 뜻 함
* AOP 주요개념
- advice 5종류
종류 | 어노테이션 | 설명 |
Before Advice | @Before | 대상 메소드가 실행되기 전에 적용할 어드바이스를 정의 |
AfterReturning Advice | @AfterReturning | 대상 메소드가 성공적으로 실행되고 결과값을 반환한 후 적용할 어드바이스를 정의 |
AfterThrowing Advice | @AfterThrowing | 대상 메소드가 예외가 발생했을때 적용할 어드바이스를 정의. try/catch문의 catch와 비슷한 역할을 함 |
After Advice | @After | 대상 메소드의 정상적인 수행여부와 상관없이 무조건 실행되는 어드바이스를 정의 . 즉 예외가 발생하더라도 실행되기 때문에 자바의 finally와 비슷한 역할을 함 |
Around Advice | @Around | 대상 메소드의 호출 전후, 예외발생등 모든 시점에 적용할 수 있는 어드바이스를 정의 . 가장 범용적으로 사용할수 있는 어드바이스 |
- 포인트컷
execution, within, bean 명시자
1) execution
가장 대표적이고 강력한 지시자로 접근 제어자, 리턴 타입, 타입패턴, 메소드, 파라미터 타입, 예외 타입등을 조합해서 가장 정교한 포인트컷을 만들 수 있다.
execution 이용해서 포인트컷 표현식을 설정할 때 사용하는 표현
* 모든값의미
예] select* 는 select로 시작하는 모든 메소드 의미
** 0개 이상 의미. 0개 이상은 파라미터 , 메소드, 패키지 등 모든것을 의미
패키지 표현하면 하위의 모든 패키지를 의미하고 파라미터를 표현하면 파라미터 개수와 관계없이 모든 파라미터 의미
예] execution (* board.controller.*(..)) : board.controller 패키지 밑에 파라미터가 0개 이상인 모든 메소드 호출
execution (* board..controller.insert*(..)): board 패키지의 모든 하위 패키지에 controller 패키지 밑의 insert로 시작하는 파라미터가 0개 이상인 모든 메소드 호출
execution (* board..service.insert*(..) || * board..service.update*(..)) 이런식으로 AOP이용한 트랜잭션 사용
2) within
특정 타입에 속하는 메소드를 포인트컷으로 설정
예] within(board.service.*ServiceImpl) : board.service패키지 밑에 ServiceImpl이라는 이름으로 끝나는 메소드 호출
3) bean
스프링의 빈 이름의 패턴으로 포인트컷을 설정
예] bean(boardServiceImpl) : boardServiceImpl이라는 이름을 가진 빈의 메소드 호출
bean(*ServiceImpl) : ServiceImpl이라는 이름으로 끝나는 빈의 메소드 호출
* AOP 적용하기
package board.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
@Aspect //AOP설정
public class LoggerAspect {
private Logger log = LoggerFactory.getLogger(this.getClass());
//@Around 어드바이스의 종류, execution은 포인트컷 표현식으로 적용할 메소드 명시
@Around("execution(* board..controller.*Controller.*(..)) or"
+" execution (* board..service.*Impl.*(..)) or"
+" execution (* board..dao.*Mapper.*(..))" )
public Object logPrint(ProceedingJoinPoint joinPoint) throws Throwable{
String type = "";
String name = joinPoint.getSignature().getDeclaringTypeName();
if(name.indexOf("Controller")>-1) {
type = "Controller \t :";
}else if(name.indexOf("ServiceImpl")>-1) {
type = "ServiceImpl \t :";
}else if(name.indexOf("Mapper")>-1) {
type = "Mapper \t\t :";
}
log.debug(type + name+"."+joinPoint.getSignature().getName()+"()");
return joinPoint.proceed();
}
}
'SpringBoot > (책)스프링부트 시작하기' 카테고리의 다른 글
[springboot] 9. 예외처리하기 (0) | 2023.04.25 |
---|---|
[springboot] 8. 트랜잭션 적용하기 (0) | 2023.04.24 |
[springboot] 6. HandlerInterceptor(인터셉터) 사용하기 (0) | 2023.04.23 |
[springboot] 5-1. Log4JDBC로 쿼리 로그 정렬하기 (0) | 2023.04.23 |
[springboot] 5. springboot Logback 설정하기 (0) | 2023.04.23 |