AOP(Aspect Oriented Programming)
AOP(Aspect Oriented Programming)란 풀 네임을 해석하면 관점 지향 프로그래밍으로, 핵심 로직과 부가 기능을 분리하여 애플리케이션 전체에 걸쳐 사용되는 부가 기능을 모듈화 하여 재사용할 수 있도록 지원해 줍니다.
여기서 모듈화란 공통된 로직이나 기능을 하나의 단위로 묶는 것을 의미하며, AOP를 간단하게 해석하기 위해 예를 들자면, 핵심적인 관점은 비즈니스 로직이 될 수 있고, 부가적인 관점은 핵심 로직을 실행하기 위해 행해지는 데이터베이스 연결, 로깅, 파일 입출력 등이 될 수 있습니다.
Aspect(측면, 관점, 관심)
Aspect는 부가기능을 정의한 코드인 Advice와 해당 Advice를 적용하는 걸 결정하는 PointCout을 합친 개념입니다.
AOP 개념을 적용하면 핵심 기능 코드 사이에 침투된 부가 기능을 독립적인 Aspect로 구분해 낼 수 있고, 구분된 부가기능 Aspect를 RunTime 시에 필요한 위치에 동적으로 참여하게 할 수 있습니다.
간단하게 정리하면 다음과 같습니다.
※
핵심적인 비즈니스 로직은 아니지만 반드시 해야 하는 작업들
ex) 버스, 지하철로 출퇴근을 할 때 교통카드를 찍어야 함, 목적지에 정시에 도착하는 것이 중요하고 교통카드를 찍는 행위가 메인은 아님.
- 관심의 분리(Separation of Concerns)를 통해 핵심관점(업무로직) + 횡단관점(트랜 잭션, 로그, 보안, 인증 처리 등)으로 관심의 분리를 실현
-장점 : 중복되는 코드 제거, 효율적인 유지 보수, 높은 생산성, 재활용성 극대화, 변화 수용의 용이성
AOP 주요 용어
- Aspect : 공통 관심사(로깅, 보안, 트랜잭션 등)
- Join Points : Method를 호출하는 시점, 예외가 발생하는 시점 등과 같이 특정 작업이 실행되는 시점을 의미한다.
- Advice : Join Points에서 실행되어야 하는 코드(실제로 AOP 기능을 구현한 객체)
- Pointcuts : 실제로 Advice를 적용시킬 대상 method
- Proxy : Advice가 적용되었을 때 만들어지는 객체
Advice의 종류
- Before : target method 호출 전에 적용
- After : target method 호출 후에 적용
- Around : target method 호출 이전과 이후 모두 적용(가장 광범위하게 사용된다.)
ex ) 로그인 전/후의 각 페이지 처리 등
AOP 설정
Maven을 사용하시는 분들은 AOP 관련 라이브러리를 pom.xml 파일에 추가하셔야 합니다.
위 사진처럼 라이브러리를 설정하고 업데이트하시고, servlet-context.xml 파일에 aop 태그를 추가해 주면 됩니다.
AOP 설정은 예제용으로, 로깅 변수를 추가해서 해당 페이지 요청해서 view단까지의 로딩 시간을 콘솔창에 띄우려고 합니다.
package com.example.spring.aop;
import org.apache.catalina.tribes.util.Arrays;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component //스프링에서 관리하는 범용 bean (참고:DAO에서 @Repository대신 적용가능)
@Aspect //공통적인 업무를 지원하는 aop bean
public class LogAdvice {
//로깅을 위한 변수
private static final Logger logger=LoggerFactory.getLogger(LogAdvice.class);
//@Before(핵심업무 전), @After(핵심업무 후), @Around(핵심업무 전,후 모두 사용)
// ..은 모든 하위패키지를 의미, *(..)는 모든 메소드를 의미
//@시점("범위" or "범위" or "범위"...)
@Around("execution(* com.example.spring02.controller..*Controller.*(..))"
+ " or execution(* com.example.spring02.service..*Impl.*(..))"
+ " or execution(* com.example.spring02.model..dao.*Impl.*(..))")
public Object logPrint(ProceedingJoinPoint joinPoint) throws Throwable {
//핵심업무가 실행되는 시점에 수행할 메소드
long start=System.currentTimeMillis();//시스템의 밀리세컨드값
Object result=joinPoint.proceed();
String type=joinPoint.getSignature().getDeclaringTypeName();
String name="";
if(type.indexOf("Controller") > -1) {
name="Controller : "; //콘솔창에 Controller : 표시됨
}else if(type.indexOf("Service") > -1) {
name="ServiceImpl : ";
}else if(type.indexOf("DAO") > -1) {
name="DAOImpl : ";
}
//호출한 클래스, method 정보를 로거에 저장
logger.info(name+type+"."+joinPoint.getSignature().getName()+"()");
//메소드에 전달되는 매개변수들을 로거에 저장
logger.info(Arrays.toString(joinPoint.getArgs()));
long end=System.currentTimeMillis();
long time=end-start;
logger.info("실행시간 : " + time);
return result;
}
}
마치며
오늘은 AOP에 대해서 포스팅해보았습니다.
다음 포스팅에서 뵙겠습니다.
'[ JAVA ] > JAVA Spring' 카테고리의 다른 글
[ Spring ] 페이지네이션 코드 해석 및 기록 (1) | 2023.06.19 |
---|---|
[ Spring ] Component Scan (0) | 2023.05.26 |
[ Spring Boot ] Spring boot 개요 및 설정 (0) | 2023.05.08 |
[ Spring ] 도로명주소 API 연동 (0) | 2023.04.27 |
[ Spring ] 게시판 02 - 회원 목록 페이지 나누기 기능 구현 (0) | 2023.04.26 |