728x90
AOP 용어
Aspect
여러 객체에 공통으로 적용되는 공통 관심 사항을 Aspect라고 한다.
Target
우리가 위빙할 대상을 Target이라고 한다.
Pointcut
JoinPoint를 적용할 영역을 지정한다.
JoinPoint
클래스의 인스턴스 생성 시점', '메소드 호출 시점(앞, 뒤 등)', '예외 발생 시점'과 같이 특정 시점을 조인포인트라고 한다.
- 1) @Around
- 2) @Before
- 3) @After
- 4) @AfterThrowing
- 5) @AfterReturning
Advice
조인 포인트에 삽입되어져 실질적으로 동작하는 코드를 Advice라고 한다.
/@Configuration Controller전에 쓰고
@Component Controller 가 뜨고난 후
@Component
@Aspect
AOP 리턴까지가능(앞뒤로 되니까)
실습해보기
스프링을 사용하지 않고 자바에서 AspectJ만 실습해보자
AspectJ는 AspectJ 코드 기반 스타일과 어노테이션 기반으로 AOP구현이 가능하다.
이번 실습에는 AspectJ5부터 제공하는 어노테이션 기반 AspectJ를 사용하겠다.
1. 의존성 추가
AspectJ 런타임 의존성 외에도 로드 시간에 Java 클래스에 대한 advice를 제공하기 위해 aspectjweaver.jar도 포함해야한다.
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.7</version>
</dependency>
2. ValidationAdvice.java
@Component //RestController Service 든 Component 구현체들이다. Compoenet 를 상속해서 만들어져있음
@Aspect //aop 처리를 할수있는 핸들러
public class ValidationAdvice {
// web 패키지에서 Controller로 끝나는 모든클래스에서 모든 메서드의 파라미터가 뭐든상관없는거를 호출
@Around("execution(* com.cos.photogramstart.web.api.*Controller.*(..))")
public Object apiAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("web api 컨틀롤러==============");
Object [] args=proceedingJoinPoint.getArgs();
for (Object arg:args){
if (arg instanceof BindingResult){
System.out.println("유효성 검사를 하는 함수입니다");
BindingResult bindingResult=(BindingResult) arg;
if(bindingResult.hasErrors()){
Map<String,String> errorMap=new HashMap<>();
for(FieldError error:bindingResult.getFieldErrors()){
errorMap.put(error.getField(), error.getDefaultMessage());
}
throw new CustomVaildationApiException("유효성검사 실패함",errorMap);
}
}
}
// ProceedingJoinPoint 함수의 모든곳에 접근할수있는 변수
// 호출한 함수보다 먼저 실행이됨
return proceedingJoinPoint.proceed(); //호출한 함수가 실행됨
}
@Around("execution(* com.cos.photogramstart.web.*Controller.*(..))")
public Object advice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
// ProceedingJoinPoint 는 컨트롤러 메소드안에 접근할수있는 권한을 만듬
System.out.println("web 컨틀롤러==============");
Object [] args=proceedingJoinPoint.getArgs();
for (Object arg:args){
if (arg instanceof BindingResult){
BindingResult bindingResult=(BindingResult) arg;
if(bindingResult.hasErrors()){
Map<String,String> errorMap=new HashMap<>();
for(FieldError error:bindingResult.getFieldErrors()){
errorMap.put(error.getField(),error.getDefaultMessage());
}
throw new CustomVaildationException("유효성검사 실패함",errorMap);
}
}
}
return proceedingJoinPoint.proceed();
}
}
예를 들어 로그인과 회원가입을 하는로직이 있다고 생각을해보자.
- 전처리기능 : 유효성검사 및 보안처리
1. 로그인기능(핵심기능)
- 후처리기능: log를 파일에 저장( 몇시몇분에 로그인을 하였는가)
- 전처리기능 : 유효성검사 및 보안처리
2. 회원가입기능(핵심기능
- 후처리기능: log를 파일에 저장( 몇시몇분에 로그인을 하였는가)
이렇게 반복되어있는 전처리와 후처리과정을 AOP를 활용하여 공통로직을 하나의 클래스에서
처리를 해주면 Contoller에서의 로직의 가독성은 좀 더 편해질 것 이다.
728x90
'aop' 카테고리의 다른 글
Sentry.io를 이용하여 Log를 한눈에 보기 (0) | 2023.02.20 |
---|---|
Spring Filter,Interceptor,AOP 차이 (0) | 2023.02.19 |
AOP란 무엇인가 (0) | 2022.08.17 |