
Aop란?
AOP(Aspect-Oriented Programming)는 스프링 프레임워크에서 제공하는 기능 중 하나로, 애플리케이션의 핵심 로직과는 별개로 여러 모듈에서 공통적으로 사용되는 기능들을 분리하여 모듈화하는 프로그래밍 패러다임. AOP는 핵심 로직에 영향을 주지 않으면서, 여러 모듈에서 반복적으로 사용되는 기능들을 재사용하고 관리하기 쉽게 만들어준다.
AOP(Aspect-Oriented Programming)는 관점(Aspect) 과 조언(Advice) 이라는 개념이 있다.
관점은 애플리케이션에서 특정 기능을 구현한 모듈
애플리케이션의 여러 부분에 걸쳐서 반복적으로 사용되는 기능들을 추상화하여 모듈화한 것이다.
조언은 관점이 적용되어야 할 지점을 지정하고, 해당 지점에서 실행되어야 할 코드
조언은 관점이 특정 시점에 어떻게 동작해야 하는지를 결정한다.
애플리케이션의 핵심 로직과는 별개로 여러 모듈에서 공통적으로 발생하는 기능.
여러 메서드에서 로깅을 수행해야 한다면 각 메서드마다 로깅 코드를 중복해서 작성해야한다. 이런 경우, 횡단 관심사를 분리하여 모듈화할 수 있으면 코드 중복을 줄이고 유지보수성을 향상시킬 수 있다.
AOP를 사용하면 횡단 관심사를 중앙에서 관리하여 코드 중복을 줄이고 유지보수성을 향상시킬 수 있습니다. 또한, 횡단 관심사의 변경이나 추가가 필요할 때도 핵심 로직에 영향을 주지 않고 AOP 설정을 변경함으로써 쉽게 대응할 수 있습니다. 이는 애플리케이션의 유연성과 확장성을 높여줍니다.



파란색pen을 준비해요 , pen을 닫고 마무리 해요! 의 기능이 중복되는 것을 확인 할 수 있다.이 중복되는 기능을 횡단 관심사이며, 이 코드를 분리하여 모듈화 한다면 코드가 훨씬 간결해질것이다!
[WritingAspect]
@Aspect
@Component //bean으로 만들기 위한 어노테이션
public class WritingAspect {
@Before("execution(void write*())")
public void prepare() {
System.out.println("파란색 pen을 준비해요!");
}
@After("execution(void write*())")
public void end() {
System.out.println("pen을 닫고 마무리 해요 ! ");
}
}
spring이 관리하는 bean 의 메소드가 수행되기 이전(before)에 적용되는 aspect
@Before와 @After로 메소드의 실행 시점을 정할 수 있다!
[메소드 pattern]
* 리턴 type => void
* 메소드명 => write로 시작하는 메소드
* 메소드의 매개변수 => 없음
* Aspect가 적용되는 위치를 "point cut"이라고 한다.
: wirte라는 모든 메소드가 실행되기전에 적용해라


[message]

[MessageAspect]
@Around("execution(void send*(..))")
public void checkGreeting(ProceedingJoinPoint joinPoint) throws Throwable {
//메소드에 전달된 인자들 목록을 얻어내기
Object[] args=joinPoint.getArgs();
for(Object tmp:args) {
//만일 String type 이면
if(tmp instanceof String) {
//원래 type 으로 casting
String msg=(String)tmp;
System.out.println("aspect 에서 읽어낸 내용:"+msg);
if(msg.contains("안녕하세요")) {
System.out.println("안녕하세요 금지된 단어 입니다.");
return; // 메소드를 끝내기
}
}
}
//aspect 가 적용된 메소드가 호출 되기 직전에 할 작업은 proceed() 호출전에 한다.
// proceed() 를 호출해야 aspect 가 적용된 메소드가 실행이된다.
joinPoint.proceed();
//aspect 가 적용된 메소드가 호출 되기 직전에 할 작업은 proceed() 호출 이후에 한다.
System.out.println("aspect 가 적용된 메소드가 리턴 했습니다.");
}
"안녕하세요 금지된 단어입니다" 를 리턴하고, 그렇지 않다면 aspect에서 읽어낸 내용을 출력한다! 

@Around("execution(String com.example.aop.util.*.get*())")
public Object checkReturn(ProceedingJoinPoint joinPoint) throws Throwable {
// aspect 가 적용된 메소드를 수행하고 리턴되는 데이터 받아오기
Object obj=joinPoint.proceed();
//원래 type 으로 casting 해서 조사해 볼수가 있다.
String a = (String)obj;
//조사후 아예 다른 값을 리턴해 줄수도 있다.
//return obj;
return "놀자 놀자";
}
놀자 놀자 를 리턴한다는 코드이다. 
