AOP(Aspects - Oriented Programming)
핵심관심사와 횡단관심사를 분리하여 모듈화하여 재사용할 수 있도록 지원하는 것
관점 지향 프로그래밍이라고도 함
스프링 AOP는 인터페이스 기반으로 함.
class Teacher{
public void sleep(){};
public void eat(){};
public void teach(){};
}
class Student{
public void sleep(){};
public void eat(){};
public void learn(){};
}
위의 코드를 보게 되면
먹고 자는 행동은 학생과 선생님 둘 다 공통적으로 수행하는 부분이기 때문에 횡단관심사라고 하고
선생님의 역할을 가르치는 것이고 학생의 역할은 배우는 것으로 서로 핵심적인 역할이기 때문에 이를 핵심관심사라고 함.
AOP를 쉽게 말하면 공통적인 부분을 재사용하는 기법이라고 할 수 있다.
스프링 AOP는 런타임에 적용되는 방식만을 추구하고 있다.
또한 AOP는 Proxy Pattern을 이용하는 방식이다.
Proxy Pattern에 대해서는 아래의 글을 참고바란다.
2023.06.08 - [JAVA-SOLID] - [OOP] 디자인 패턴(Adapter, Proxy, Decorator Pattern)
AOP 용어
AOP에는 많은 용어가 있다. 대표적으로 Joinpoint, Pointcut, Aspect, Advice등이 있다.
Joinpoint
- Aspect 적용이 가능한 모든 지점을 의미한다.
- 스프링 AOP는 인터페이스 기반이고, 인터페이스는 추상메소드의 집합체이기 때문에 메소드에만 적용이 가능함. 즉 Joinpoint 또한 메소드 실행시점만 가능하다.
Pointcut
- 공통적인 로직을 담당하는 횡단관심사를 적용할 타킷 메소드를 선택하는 지시자
- Pointcut 또한 메소드 실행시점만 가능하다.
Advice
- Pointcut에 언제(when)라는 개념까지 포함한다.
즉, Pointcut에 언제, 무엇을 적용할지 정의한 것이다. - @Around, @Before, @After, @AfterReturning, @AfterThrowing 총 5가지의 종류가 있다. 각각의 어노테이션은 AOP가 적용되는 시점을 의미한다.
<@Before>
Joinpoint 이전에 실행을 의미
<@AfterReturning>
Joinpoint 정상완료 후 실행
<@AfterThrowing>
만약 메소드가 예외를 던지는 경우에 실행
<@After>
Joinpoint의 정상, 예외 동작과는 무관하게 실
<@Around>
앞에 말한 4가지의 어노테이션을 모두 포함
@Aspect
해당 어노테이션을 사용하면 해당 클래스를 이제 AOP에서 사용하겠다는 의미이다.
Aspect = Advice + Pointcut을 의미한다.
AOP 예제
@Aspect
@Component
public class TimeTraceAop {
@Around("@annotation(auhh)")
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
System.out.println("START: " + joinPoint.toString());
try {
return joinPoint.proceed();
} finally {
long finish = System.currentTimeMillis();
long timeMs = finish - start;
System.out.println("END: " + joinPoint.toString() + " " + timeMs + "ms");
}
}
}
위의 코드를 보면 @Component어노테이션을 이용하여 TimeTraceAop클래스를 빈으로 등록하고
@Aspect을 이용하여 AOP로 등록을 하였다.
AOP에서 타깃메소드를 정하는 방식은 대표적으로 2가지가 있는데 첫번째로는
execution(*)을 이용하여 Aspect를 실행할 수 있고 위 코드에서 사용한 어노테이션을 이용하는 방법도 있다.
우선 어노테이션을 이용한 Aspect실행하는 방법은 사용자가 직접 어노테이션을 구현해서 사용해야 한다.
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface auhh {
}
위의 코드가 사용자가 지정한 어노테이션인데 @Target은 어떤 타입에 Aspect를 적용할 지 나타내는 것이고,
@Retention은 언제 적용할 지를 나타내는 어노테이션이다.
@Component
public class HelloController {
@auhh
public String Hello(Model model) {
model.addAttribute("data", "hello!!");
return "hello";
}
즉 auhh가 붙은 어노테이션은 메소드타입에 적용하고 런타임시에 적용한다는 의미이다.
위처럼 빈으로 등록된 클래스에 @auhh가 붙어있기 때문에 Hello()메소드는 AOP를 적용되었다.
@Aspect
@Component
public class TimeTraceAop {
@Around("execution(* Hello.hello_spring..*(..))")
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
System.out.println("START: " + joinPoint.toString());
try {
return joinPoint.proceed();
} finally {
long finish = System.currentTimeMillis();
long timeMs = finish - start;
System.out.println("END: " + joinPoint.toString() + " " + timeMs + "ms");
}
}
}
※ execution([접근제어자], 리턴타입 [패키지] 메서드이름(파라미터))
위의 코드는 execution(*)키워드를 이용하여 Aspect를 이용한다는 의미인데
Hello.hello_spring패키지 하위의 모든 클래스에게 적용을 한다는 의미이다.
'JAVA-SOLID' 카테고리의 다른 글
[OOP] 스프링 삼각형(IoC/DI) (0) | 2023.06.18 |
---|---|
[OOP] 디자인 패턴(Singleton, Template Method, Strategy) (0) | 2023.06.14 |
[OOP] 디자인 패턴(Adapter, Proxy, Decorator Pattern) (0) | 2023.06.08 |
[OOP] 객체지향설계 5원칙_SOLID원칙 (0) | 2023.06.08 |
[OOP] 자바 vs 구조적/절차적 프로그래밍 (0) | 2023.05.30 |