반응형
AOP란?
어떠한 로직을 기준으로 핵심적인 관점과 부과적인 관점으로 나눠 각각 모듈화 하는 방식이다.
관점을 기준으로 모듈화 한다는 것은, 코드를 부분적으로 나누어서 모듈화하겠다는 것.
이 관심사를 Crosscutting Concerns(흩어진 관심사)라고 부르며 이를 모듈화 한것이 Aspect이다.
주요 개념
- Aspect : 흩어진 관심사를 모듈화 한 것,
- Target : Aspect를 적용하는 곳
- Advice : 실질적인 기능을 담은 구현체
- JointPoint : Advice가 적용될 위치
- PointCut : JointPoint의 상세 스펙 정의. ex) A메서드 호출 전,후로 호출할 것
스프링 aop 특징
- 접근제어 및 부가가능을 추가하기 위해 프록시 패턴 기반의 AOP 구현체를 사용한다.
- 스프링 빈에만 AOP를 적용 가능하다.
- 스프링 IoC와 연동해 중복코드나 번거로움 및 객체간 복잡도등에 대한 해결책 지원이 목적이다.
(모든 AOP를 지원하는것은 아니다.)
AOP 만들기
@Component를 붙여 빈으로 등록하고 @Aspect로 Aspect 클래스임을 명시하면 된다.
예제로 사용할 코드는 메서드의 수행에 걸리는 시간을 측정하는 Aspect입니다.
아래의 코드는 com.example 패키지 밑에 있는 모든 클래스에 적용을 하고, EventService 밑에 있는 모든 메소드에 적용해라 라는 뜻입니다.
@Component
@Aspect
public class PerfAspect {
@Around("execution(* com.example..*.EventService.*(..))")
public Object logPerf(ProceedingJoinPoint pjp) throws Throwable{
long begin = System.currentTimeMillis();
Object retVal = pjp.proceed(); // 메서드 호출 자체를 감쌈
System.out.println(System.currentTimeMillis() - begin);
return retVal;
}
}
@Around : 타겟 메서드를 감싸 Advice를 실행시킨다는 이미
execution은 saelobi이하 EventService객체 모든 메서드에 해당 Aspect를 적용
public interface EventService {
void createEvent();
void publishEvent();
void deleteEvent();
}
@Component
public class SimpleEventService implements EventService {
@Override
public void createEvent() {
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println("Created an event");
}
@Override
public void publishEvent() {
try {
Thread.sleep(1000);
} catch (InterruptedException e){
e.printStackTrace();
}
System.out.println("Published an event");
}
@Override
public void deleteEvent() {
System.out.println("Delete an event");
}
}
@Service public class AppRunner implements ApplicationRunner {
@Autowired EventService eventService;
@Override public void run(ApplicationArguments args) throws Exception {
eventService.createEvent();
eventService.publishEvent();
eventService.deleteEvent();
}
}
/*
Created an event
1003
Published an event
1000
Delete an
event 0
*/
경로지정 방식 뿐 아니라, 특정 어노테이션이 붙은 포인트에 실행시킬수도 있다.
//경로지정 방식
@Around("execution(* com.example..*.EventService.*(..))")
//annotation이 붙은 포인트에 실행하는 방식
@Around("@annotation(PerLogging)")
@Component
public class SimpleEventService implements EventService {
@Override
@PerLogging
public void createEvent() {
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println("Created an event");
}
@Override
@PerLogging
public void publishEvent() {
try {
Thread.sleep(1000);
} catch (InterruptedException e){
e.printStackTrace();
}
System.out.println("Published an event");
}
@Override
@PerLogging
public void deleteEvent() {
System.out.println("Delete an event");
}
}
@Around 외에 Aspect 실행 시점을 지정하는 annotation들
- @Before (이전) : 어드바이스 타겟 메소드가 호출되기 전에 어드바이스 기능을 수행
- @After (이후) : 타겟 메소드의 결과에 관계없이(즉 성공, 예외 관계없이) 타겟 메소드가 완료 되면 어드바이스 기능을 수행
- @AfterReturning (정상적 반환 이후)타겟 메소드가 성공적으로 결과값을 반환 후에 어드바이스 기능을 수행
- @AfterThrowing (예외 발생 이후) : 타겟 메소드가 수행 중 예외를 던지게 되면 어드바이스 기능을 수행
- @Around (메소드 실행 전후) : 어드바이스가 타겟 메소드를 감싸서 타겟 메소드 호출전과 후에 어드바이스 기능을 수행
반응형
'IDE & Framework > Spring' 카테고리의 다른 글
[단축 URL 프로젝트 URLumberjack] - devOps 정의 (0) | 2023.04.24 |
---|---|
Spring boot 서버를 Gradle로 build해 jar로 직접 배포하기 (0) | 2022.06.29 |
[Spring] MyBaits Insert 후 ID 받기 (짧) (0) | 2022.05.23 |
Spring DI, IoC (0) | 2022.05.03 |
[Spring] @Scheduled cron 표현식 (0) | 2022.04.19 |