스프링의 3대 기술은 무엇인가?
Ioc/DI, PSA AOP가 존재한다.
AOP란 관점지향 프로그래밍으로서 각각의 관점에 대해 정리를 하겠다가 골자이다.
말로 설명하면 이해가 안되니 바로 예제를 보자
public class Calculator {
private int value;
public Calculator(int value) {
this.value = value;
}
public void add(int value) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
this.value += value;
stopWatch.stop();
System.out.println(stopWatch);
}
public void sub(int value) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
this.value -= value;
stopWatch.stop();
System.out.println(stopWatch);
}
public void mul(int value) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
this.value *= value;
stopWatch.stop();
System.out.println(stopWatch);
}
public int get() {
return value;
}
}
자 여기서 중복이 되는 코드가 StopWatch 뭐시기인거는 자명하다.
StopWatch stopWatch = new StopWatch(); stopWatch.start(); //this.value += value; stopWatch.stop(); System.out.println(stopWatch);
말 그대로 연산이 얼마나 걸릴지를 시간측정하는 프로그램으로써 위의 문장들이 중복이 되는것들을 우리는 파악 할 수 있다.
이렇게 반복이 되는 기능이나 관심사들을 Cross Cutting Concern 이라고 일컫는다.
그리고 이러한 Cross cutting Concern을 분리해내는것이 AOP의 핵심이라고 생각하면 될것 같다.
// Aspect를 적용할 대상을 지정하는 포인트컷 예시
// com.example 패키지 내의 모든 public 메서드
pointcut publicMethods() : execution(public com.example..(..));
// Service 클래스의 모든 메서드
pointcut serviceMethods() : execution( com.example.Service.(..));
// com.example 패키지 내의 모든 클래스의 모든 메서드
pointcut allMethods() : execution( com.example..(..));
// com.example 패키지 내의 모든 메서드 중 이름이 'get'으로 시작하는 메서드
pointcut getMethods() : execution( com.example..get*(..));
@Aspect @Component public class PerformanceCheck { @Around("execution(* com.example.blogjava..*(..))") public Object printlnPerf(ProceedingJoinPoint joinPoint) throws Throwable { StopWatch stopWatch = new StopWatch(); stopWatch.start(); Object proceed = joinPoint.proceed(); stopWatch.stop(); System.out.println(stopWatch); return proceed; } }
@Around가 여기서는 advice를 나타내며
"execution 뭐시기"가 pointcut를 나타낸다.
그리고 jointpoint는 Object proceed = joinPoint.proceed(); 이부분을 나타낸다. 즉 여기에 mul,add,sub 이게 들어가는것이다.
Weaving
위빙은 포인트컷에 해당하는 특정 메소드가 어드바이스를 만난다면 그것을 삽입하는 과정을 의미합니다.
6-1 .컴파일 타임(Compile Time Weaving): 컴파일할 때 AspectJ 컴파일러를 사용하여 Aspect를 AspectJ 바이트 코드로 변환하는 방법입니다.
6-2. 로드 타임(Load Time Weaving): 클래스를 로딩하는 시점에 AspectJ 바이트 코드를 로드하여 Aspect를 적용하는 방법입니다.
6-3. 런타임(Run Time Weaving): 애플리케이션이 실행되는 시점에 Aspect를 적용하는 방법입니다.
// Aspect 정의
public aspect LoggingAspect { // Pointcut 정의: com.example 패키지 내의 모든 public 메서드를 대상으로 함 pointcut publicMethods() : execution(public * com.example.*.*(..)); // Before Advice: publicMethods()에 해당하는 메서드가 실행되기 전에 로그를 출력함 before() : publicMethods() { System.out.println("Before advice: Method is about to be executed."); } // After Advice: publicMethods()에 해당하는 메서드가 정상적으로 반환된 후에 로그를 출력함 after() : publicMethods() { System.out.println("After advice: Method has been executed successfully."); } // After Throwing Advice: publicMethods()에 해당하는 메서드가 예외를 던진 후에 로그를 출력함 after() throwing(Exception ex) : publicMethods() { System.out.println("After throwing advice: Method has thrown an exception - " + ex.getMessage()); } // Around Advice: publicMethods()에 해당하는 메서드 실행 전후에 로그를 출력함 Object around() : publicMethods() { System.out.println("Around advice: Before method execution."); Object result = proceed(); // 메서드 실행 System.out.println("Around advice: After method execution."); return result; } }