2023. 7. 3. 18:57ㆍTIL(Today I Learned)
(1) AOP란?
- AOP는 Aspect Oriented Programming이다. 특정 관점에 대해서 프로그래밍을 하는 것이다.
- 현재까지의 작업 내용을 Controller, Service, Dao 이렇게 했었는데 AOP는 서비스 관점에서 프로그래밍을 한다는 것이다.
- 예시를 들자면 db 왔다갔다 할 때, 시간이 꽤 걸린다. 프로그래밍이 느리다 싶으면 was, db랑 통신할 때(dao)에서 db까지 왓다갔다할때, 좀 오래 걸릴 수가 있다.
- 이게 느리다 싶으면 쿼리문에 문제가 있는거 아닌가 확인할 필요가 있다. 그래서 dao에 log를 활용해서 쿼리문들이 실행되는 시간을 측정할 필요가 있다.
- 특정 기능 하나에다가 추가하는게 아니라 모든 기능에 추가할 수 있다.
- dao를 타겟으로 삼아서 쿼리문을 실행되게 한다. 이럴 때 사용하는 것이 aop다.
- aop를 활용하면 dao 클래스에 있는 모든 메소드에 동일 작업을 추가할 수 있다.
- aop를 활용하면 시작 시간과 끝 시간의 차이를 잴 수 있다.
- 실제로 추가하는 게 아니라, aop는 proxy 객체를 추가해서 시간을 잰다.
- proxy는 기존의 객체를 감싸는 객체라 할 수 있다. aop는 proxy 객체를 활용해서 돌아간다.
- 기존의 방식은 MemberDao 접근해서 join 메소드를 호출하는 것이다. proxy가 적용되면 임시 proxy가 하나 만들어지고 이 proxy를 통해서 join을 호출한다.
- 그래서 proxy 객체를 이용해서 join 메소드 앞뒤로 코드를 추가하는 것이 가능하다.
- 관점지향이란 controller, service, dao가 있고 c,s,d순으로 되었더라면 특정 관심사들만 가지고 개발을 하고 싶을 때,
예를 들어 dao들만 쓰고 싶을 때, service 들만 쓰고 싶을 때는 모든 클래스의 메소드를 찾아서 전부다 코드를 추가하는 것이 아니라 aop를 활용해서 그것을 타겟으로 삼아서 하고싶은 내용을 앞뒤로 추가할 수가 있다.
- AOP는 스프링의 기술이 아니다.
(2) RestController
@ResponseBody와 @Controller를 합친 것을 일컫는다.
(3) aop 설정 방법
<aop:aspectj-autoproxy/>
-> aop에 대한 aspect proxy를 자동으로 설정하겠다는 뜻
1. pom.mxl에 라이브러리 3개 추가
2. root-context.xml에 태그 2개 추가
<사용법>
1. when
- before : 타겟 실행 이전에 동작
- after : 타겟 실행 이후에 동작
- afterThrowing : 타겟 실행 이후, 에러가 있을때 동작
- afterReturning : 타겟 실행 이후, 에러가 없을 때 동작
- around : 타겟 실행 시점을 지정 가능, 무조건 return을 해줘야 한다.
컨트롤러 객체, 서비스 객체, dao객체 이렇게 흘러가는게 아니라 dao를 감싸는 daoProxy객체가 있는 것이다. 즉,
service가 호출하는게 프록시를 호출하는것이기 때문에 프록시가 return을 해줘야 service에 값이 전달이 된다.
target
- 특정 인터페이스, 클래스를 지정할 때, 사용함(자식들도 포함)
- ex)
within
- 특정 패키지 or 클래스의 모든 메소드
ex) @Around() 같은 시점을 지정하는 어노테이션을 지정해주고 (within("패키지 or 클래스"))를 넣어줌
ex)
@Around("within(com.swy.app.aop.TestSErviceImpl)")
@Around("within(com.swy.app.aop.*)")
@Around("within(com..*)")
execution
- 표현식으로 형태 지정
aop 코드 예시
package com.kh.app.aop.timer;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import lombok.extern.slf4j.Slf4j;
@EnableAspectJAutoProxy
@Aspect
@Slf4j
public class TimerAspect {
@Before("target(com.kh.app.member.dao.MemberDao)")
public void m01() {
log.debug("@Before~~~~~");
}
@After("target(com.kh.app.member.dao.MemberDao)")
public void m02() {
log.debug("@After~~~~~");
}
@AfterReturning("target(com.kh.app.member.dao.MemberDao)")
public void m03() {
log.debug("@AfterReturning~~~~~");
}
@AfterThrowing("target(com.kh.app.member.dao.MemberDao)")
public void m04() {
log.debug("@AfterThrowing~~~~~");
}
@Around("target(com.kh.app.member.dao.MemberDao)")
public Object m05(ProceedingJoinPoint jp) throws Throwable {
log.debug("@Around 시작~~~~~");
String str = jp.getSignature().toLongString();
System.out.println(str);
Object o = jp.proceed(); //타겟 메소드 실행
System.out.println(o);
log.debug("@Around 종료~~~");
return o;
}
}
'TIL(Today I Learned)' 카테고리의 다른 글
2023.07.12 TIL (0) | 2023.07.12 |
---|---|
2023.07.07 TIL (0) | 2023.07.07 |
2023.06.23 TIL (0) | 2023.06.23 |
2023.06.22 TIL (0) | 2023.06.22 |
2023.06.20 TIL (0) | 2023.06.20 |