혜야의 코딩스토리
[Spring] AOP 관점 지향 프로그래밍 본문
📌 AOP (Aspect Oriented Programming)
- 관점(관심) 지향 프로그래밍
- 횡단 관심사(cross-cutting concern )에 따라 프로그래밍 하는 것
- 객체지향 프로그래밍(Object Oriented Programming, OOP)를 보완하는 확장적인 개념
- 장점 : 중복되는 코드 제거, 효율적인 유지보수, 높은 생산성, 재활용성 극대화, 변화 수용의 용이성
📌 Aspect (측면, 관점, 관심)
핵심적인 비즈니스 로직은 아니지만 반드시 해야 하는 부가기능(인프라 로직)
**인프라 로직
- 애플리케이션의 전 영역에서 나타날 수 있음
- 중복코드를 만들어낼 가능성때문에 유지보수가 힘들어짐
- 비즈니스 로직과 함께 있으면 비즈니스 로직을 이해하기 어려워짐
- 이처럼 인프라 로직은 로깅, 트랜잭션, 권한검사, 성능 측정 등 하나의 관심사를 가지게 됨
- 상단의 이미지처럼 인프라 로직의 중복이 횡단으로 나타남 => cross-cutting concern 횡단 관심사
💡 따라서, AOP는 횡단 관심사에 따라 프로그래밍을 하는 것이라고 생각하면 편함
📌 AOP 용어
-Aspect : 공통 관심사(로깅, 보안, 트랜잭션 등)
-Target : 어떤 대상에 부가 기능을 부여할 것인가
-Advice : 어떤 부가기능? (Join point에서 실행되어야 하는 코드)
-Join point : 어디에 적용할 것인가? 메서드, 필드, 객체, 생성자 등 (Spring AOP에서는 메소드가 실행될 때만으로 한정함)
-Point cut : 실제 advice가 적용될 지점, Spring AOP에서는 advice가 적용될 메서드를 선정
@Around("execution ... ") => execution으로 지정하는 부분이 Point cut임
-Proxy : Advice가 적용되었을 때 만들어지는 객체
@Transactional
한 트랜잭션의 연산들은 모두 성공하거나, 반대로 모두 실패된다.
📌Advice 종류 (ex. 로그인 전/후의 각 페이지 처리 등)
Before | target method 호출 전에 적용 |
After | target method 호출 후에 적용 |
Around | target method 호출 이전과 이후 모두 적용 |
AfterReturning | target method가 실행된 후 제대로 된 결과 값을 리턴했을 때 |
AfterThrowing | target method 실행 시점에서 예외가 발생했을 때 |
package com.example.spring02.aop;
import java.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으로 등록
@Aspect //AOP(공통적인 업무를 지원하는 bean으로 등록)
public class LogAdvice {
//로깅을 위한 변수
private static final Logger logger=LoggerFactory.getLogger(LogAdvice.class);
/*
* @Before(핵심 업무 전), @After(핵심 업무 후), @Around(전,후 모두 사용)
* ..은 모든 하위 패키지를 의미, *(..)는 모든 메소드를 의미
* @시점("범위" or "범위" or "범위")
* @Before, @After => JoinPoint객체
* @Around => ProceedingJoinPoint객체
*/
@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()+"()");
//method에 전달되는 매개변수들을 로거에 저장
logger.info(Arrays.toString(joinPoint.getArgs()));
long end=System.currentTimeMillis();
long time=end-start;
logger.info("실행시간 : " + time);
return result;
}
}
참고
https://www.youtube.com/watch?v=y2JkXjOocZ4&t=2s
https://www.youtube.com/watch?v=Hm0w_9ngDpM&t=690s
'꿈 : 멋진 개발자 🧸 > Java' 카테고리의 다른 글
[Spring] Interceptor 인터셉터 (로그인 세션 체크 Interceptor로 처리하기) (0) | 2022.10.04 |
---|---|
[Spring] @RequestBody / @ResponseBody 어노테이션이란? (0) | 2022.10.01 |
[Spring] 스프링 프레임워크의 특징 (0) | 2022.09.23 |
[Spring] 스프링 회원 관리 프로그램 (0) | 2022.09.23 |
[JSP] JSP(Java Server Pages)의 내장 객체/ MVC패턴 / 프레임 워크(Framework) (0) | 2022.07.17 |