AOP란❓
Aspect Oriented Programing 의 약자로 OOP와 같은 프로그래밍 패러다임의 하나이다.
"횡단 관심사" 를 분리함으로써 모듈성을 증가시키는 것이 목적인 프로그램이다.
횡단 관심사❓
어플리케이션을 구성하는 중요한 요소임과 동시에 부가적인 기능을 담당하는 것
EX) 트랜잭션, 로깅, 성능분석
🌈관점을 나눠서 구현하자 ❗️
✏️핵심기능의 관점에서는 각각의 Service는 Board, User, XXX 으로 공통된 요소가 없다
각각의 Service는 각자 코드를 구현하고 있으나 부가기능의 관점에서 봤을땐 상황이 달라진다.
✏️부가기능의 관점에서는 각각의 Service 수행시잔 측정을 나타내는 before(), after()의 메소드가 공통되는 것을 알수 있다.
💪🏻AOP 는 여기서 시작한다.
기존 OOP에서 바라보던 관점을 달리하여 부가기능적인 측면에서 볼때,
공통된 요소를 추출하는 것 이다.
여기서 가로(횡단)영역의 공통된 부분을 잘라냈다고 하여 AOP를 크로스 컷팅 이라고 부르기도 한다.
🌈결국 공통된 기능을 재사용하는 기법이다.
🤖OOP 에서는 공통된 기능을 재사용하는 방법으로 상속, 위임을 사용한다.
허나, 전체 어플리케이션에서 수많은 부가기능들을 상속이나 위임으로 처리하기에는 무리가있다.❌
예를 보며 확인해보자
SampleService 인터페이스
public interface SampleService {
public Integer doAdd(String str1, String str2)throws Exception;
}
SampleService 구현 클래스
@Service
public class SampleServiceImpl implements SampleService {
//테스트 코드를 작성하면서 log.info()를 이용해 로그를 기록하는 부분을 AOP를 적용하여 중복 기록하는 부분을 제거 시킬것이다.
@Override
public Integer doAdd(String str1, String str2) throws Exception {
// TODO Auto-generated method stub
return Integer.parseInt(str1)+Integer.parseInt(str2);
}
}
SampleService 구현 클래스의 메서드를 이용할때 로그를 남기는 aop 적용 부분
@Component
@Log4j
@Aspect
public class LogAdvice {
//execution...문자열은 AspectJ의 표현식이다. 접근제한자와 특정 클래스의 메서드를 지정할 수 있음.
@Before( "execution(* org.zerock.service.SampleService*.*(..))")
public void logBefore() {
log.info("============================");
}
//execution으로 시작하는 포인트컷 설정에 doAdd()메서드 명시하고 파라미터값 지정함
// 뒤족 &&args 부분은 변수명을 지정 이 두 정보를 이용하여 logBeforeWithParam 메서드의 파라미터값을 설정
@Before( "execution(* org.zerock.service.SampleService*.doAdd(String,String)) && args(str1, str2)")
public void logBeforeWithParam(String str1, String str2) {
log.info("str1: "+str1);
log.info("str2: "+str2);
}
@AfterThrowing(pointcut = "execution(* org.zerock.service.SampleSerivce*.*(..))", throwing="exception")
public void logException(Exception exception) {
log.info("Exception.....!!!!!");
log.info("exception: "+ exception);
}
@Around("execution(* org.zerock.service.SampleService*.*(..))")
public Object logTime( ProceedingJoinPoint pjp) {
long start = System.currentTimeMillis();
log.info("Target: "+pjp.getTarget());
log.info("Param: "+Arrays.toString(pjp.getArgs()));
Object result = null;
try {
result = pjp.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
long end= System.currentTimeMillis();
log.info("TIME: "+(end - start));
return result;
}
}
어떤 위치에 Advice를 적용할 것인지를 결정하는 포인트 컷이다.
@Before(~~)org.zerock.service.SampleService*.*(..))")
@AfterThrowing 은 지정된 대상이 예외를 발생한 후에 동작하면서 문제를 찾을수 있도록 도와준다.
@AfterThrowing(pointcut = "execution(* org.zerock.service.SampleSerivce*.*(..))", throwing="exception")
public void logException(Exception exception)
@Around 부분은 직접 대상 메서드를 실행할 수 있는 권한을 가지고 있고, 메서드의 실행 전과 실행 후에 처리가 가능하다.
ProceedingJoinPoint는 @Around와 같이 결합해서 파라미터나 예외 등을 처리할 수 있다.
그리고 AOP의 대상이 되는 Target이나 파라미터등을 파악할 수 있고 직접 실행 결과를 결정할 수도 있음
@Before과는 달리 리턴 타입이 void가 아닌 타입으로 설정하고, 메서드의 실행 결과 역시 직접 반환하는 형태로 작성해야함
해당 테스트코드 실행시
@Test
public void testAdd() throws Exception{
log.info("testAdd[더하기 테스트]");
log.info(service.doAdd("123", "456"));
}
'SPRING > 스프링' 카테고리의 다른 글
[스프링]6. @RequestMapping 어노테이션 사용 (0) | 2021.03.30 |
---|---|
[스프링]5. @Autowired// @Component 어노테이션 사용 (0) | 2021.03.30 |
[스프링]3.스프링을 쓰는 이유? 의존성 주입 (0) | 2021.03.25 |
[스프링]2. 어노테이션 설명 (0) | 2021.03.18 |
[스프링]1. root-context.xml에서 Beans Graph 탭이 안 보일 때 (0) | 2021.03.17 |