AOP(Aspect Oriented Programming)

CHM·2022년 6월 21일
0

Spring

목록 보기
22/26

AOP

  • 애플리케이션에서의 관심사의 분리(기능의 분리) 즉, 핵심적인 기능에서 부가적인 기능을 분리한 부가기능을 Aspect라는 독특한 모듈형태로 만들어서 설계하고 개발하는 방법
  • 핵심기능과 부가기능을 분리시켜 핵심기능만 작성하고 부가기능을 별도로 작성해서 런타임 시에 이를 결합시켜 줄 수 있다.
  • 핵심 기능(Core Concerns) : 업무(Biz) 로직을 포함하는 기능
  • 부가 기능(Cross-cutting Concerns) : 핵심 기능을 도와주는 부가적인 기능(로깅, 보안)

애스팩트(Aspect)

  • 부가기능을 정의한 코드인 어드바이스(Advice)와 어드바이스를 어디에 적용할지를 결정하는 포인트컷(PointCut)을 합친 개념
  • AOP개념을 적용하면 핵심기능 코드 사이에 침투된 부가기능을 독립적인 애스팩트로 구분해낼 수 있음.
  • 애스팩트를 런타임 시에 필요한 위치에 동적으로 참여하게 할 수 있음.

AOP 용어

타깃

  • 핵심기능을 담고 있는 모듈로, 부가기능을 부여할 대상이 됨.

어드바이스

  • 타깃에 제공된 부가기능을 담고 있는 모듈

조인 포인트

  • 어드바이스가 적용될 수 있는 위치
  • 타깃 객체가 구현한 인터페이스의 모든 메서드는 조인 포인트가 됨

포인트 컷

  • 어드바이스를 적용할 타깃의 메서드를 선별하는 정규표현식(조인포인트를 나타내는 문법)
  • 포인트컷 표현식은 execution으로 시작하고, 메서드의 Signature를 비교하는 방법을 주로 이용함

위빙

  • 포인트컷에 의해서 결정된 타깃의 조인포인트에 부가기능(어드바이스)을 삽입하는 과정
  • 위빙은 AOP가 핵심기능(타깃)의 코드에 영향을 주지 않으면서 필요한 부가기능(어드바이스)을 추가할 수 있도록 해주는 핵심적인 처리과정

애스팩트

  • AOP의 기본 모듈
  • 어드바이스 + 포인트컷
  • 싱글톤 형태의 객체로 존재함

어드바이저

  • 애스팩트와 동일
  • Spring AOP에서만 사용되는 특별한 용어

Spring AOP

  • Spring AOP는 프록시 기반 AOP를 지원함
    • 타깃 객체에 대한 프록시를 만들어 제공
    • 타깃을 감싸는 프록시는 실행시간(runtime)에 생성됨
    • 프록시는 어드바이스를 타깃 객체에 적용하면서 생성되는 객체임
  • 프록시가 호출을 Intercept한다
    • 전처리 어드바이스 : 프록시는 타깃 객체에 대한 호출을 가로챈 다음 어드바이스의 부가기능 로직을 수행하고 난 후에 타깃의 핵심기능 로직을 호출함
    • 후처리 어드바이스 : 타깃의 핵심기능 로직 메서드를 호출한 후 부가기능(어드바이스)을 수행하는 경우도 있다
  • Spring AOP는 메서드 조인 포인트만 지원한다.
    • Spring은 동적 프록시를 기반으로 AOP를 구현하므로 메서드 조인 포인트만 지원
    • 즉, 핵심기능(타깃)의 메서드가 호출되는 런타임 시점에만 부가기능(어드바이스)을 적용할 수 있음
    • Spring이 아닌 AspectJ 같은 고급 AOP 프레임워크를 사용하면 다양한 작업에 부가기능 적용이 가능하다.

Spring AOP 설정 및 사용

1. 의존성 설치 : Spring-AOP, aspectj weaver

  • Maven Repository에 Spring AOP, AspectJ Weaver 검색해 dependency 복사
  • pom.xml dependencies 안에 붙여넣기

2. AOP 자동 프록시 설정 : root-context.xml

  • WEB-INF/spring 안에 root-context.xml 생성
  • namespaces에 aop 기능 체크
  • 아래 코드 추가
<aop:aspectj-autoproxy/>

3. SampleAspect 클래스 생성

@Component   // 자동 빈등록
@Aspect
public class SampleAspect {
	
    // 어떤 타겟(메서드)에 적용할 것인가
    // "" 안에 포인트 컷 문법을 작성 => hello 패키지 내의 모든 클래스의 모든 메서드를 aspect로
    @Before("execution(* kr.co.acomp.hello..*.*(..))")	
    public void before(JoinPoint joinPoint) {
    	String targetMethodName = joinPoint.getSignature().getName();
        
        System.out.println(targetMethodName + " is invoked..");
    }
}

0개의 댓글