# AOP
- 업무 로직을 포함하는 기능을 핵심기능(Core conecrens)
- 핵심기능을 도와주는 부가적인 기능(로깅, 보안 등)을 부가 기능(Cross-cutting Concerns)이라고 부른다.
- 객체 지향의 기본 원칙을 적용하여도 핵심기능에서 부가기능을 분리해서 모듈화하는 것은 매우 어렵다.
- 핵심기능과 부가기능을 별도로 관리하여 런타임 시에 처리할 수 있도록 지원하는 것이 AOP
AOP는 애플리케이션에서 관심사의 분리(기능의 분리)
- 핵심적인 기능에서 부가적인 기능을 분리
- 분리한 부가기능을 Aspect라는 독특한 모듈 형태로 만들어서 설계하고 개발하는 방법
- OOP를 적용하여도 핵심 기능에서 부가기능을 쉽게 분리된 모듈로 작성하기 어려운 문제점을 AOP가 해결
- AOP는 부가기능을 애스펙트(Aspect)로 정의 하여, 핵심기능에서 부가기능을 분리함으로써 핵심기능을 설계하고 구현할 때 객체지향적인 가치를 지킬 수 있도록 도와주는 개념임
# Aspect(Aspect = Advice + PointCut)
- 애스펙트는 부가기능을 정의한 코드인 Advice와 이를 어디에 적용할지를 결정하는 PointCut을 합친 개념
- AOP 개념을 적용하면 핵심기능 코드 사이에 침투된 부가기능을 독립적인 애스펙트로 구분해낼 수 있음
- 구분된 부가기능 애스펙트를 런타임 시에 필요한 위치에 동적으로 참여하게 할 수 있음
# AOP 용어
- Target: 핵심 기능을 담고 있는 모듈로, 타깃은 부가기능을 부여할 대상이 됨
- Advice: 부가기능을 담고 있는 모듈
- Join Point: Advice가 적용될 위치, 타깃 객체가 구현한 인터페이스의 모든 메서드는 조인 포인트가 됨
- PointCut: Advice를 적용할 타깃의 메서드를 선별하는 정규표현식(execution으로 시작하고 메서드의 Signature를 비교하는 방법을 주로 이용)
- Aspect: AOP의 기본모듈, Advice + PointCut, 싱글톤 형태의 객체로 존재
- Adviser: 어드바이저는 Aspect와 동일 용어(Spring AOP에서 사용되는 특별한 용어)
- Weaving: 위빙은 포인터컷에 의해서 결정된 타깃의 조인 포인트에 부가기능을 삽입하는 과정(핵심적인 처리과정)
# Spring AOP 특징
1) Spring은 프록시(Proxy) 기반 AOP 지원
- Spring은 타깃 객체에 대한 프록시를 만들어 제공
- 타깃을 감싸는 프록시는 실행시간에 생성됨
- 프록시는 어드바이스를 타깃 객체에 적용하면서 생성되는 객체임
2) 프록시가 호출을 가로챈다(Intercept)
- 프록시는 타긱 객체에 대한 호출을 가로챈 다음 어드바이스의 부가기능 로직을 수행하고 난 후에 타깃의 핵심기능 로직을 호출함(전처리 어드바이스)
- 타깃의 핵심기능 로직 메서드를 호출한 후에 부가기능(어드바이스)을 수행하는 경우도 있음(후처리 어드바이스)
3) Spring AOP는 메서드 조인 포인트만 지원
- Spring은 동적 프록시를 기반으로 AOP를 구현하므로 메서드 조인 포인트만 지원함
- 즉, 핵심기능(타깃)의 메서드가 호출되는 런타임 시점에만 부가기능(어드바이스)을 적용할 수 있음
- 반면에 AspectJ 같은 고급 AOP 프레임워크를 사용하면 객체의 생성, 필드값의 조회와 조작, static 메서드 호출 및 초기화 등의 다양한 작업에 부가기능을 적용할 수 있음
# 실습
의존성 설치(spring-aop, aspectj weaver)
AOP 자동 프록시 설정(root-context.xml)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<aop:aspectj-autoproxy/>
<context:component-scan base-package="kr.co.acomp.hello">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
</beans>
SampleAspect 생성
package kr.co.acomp.hello.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class SampleAspect {
@Before("execution(* kr.co.acomp.hello..*.*(..))")
public void before(JoinPoint joinPoint) {
String targetMethodName =
joinPoint.getSignature().getName();
System.out.println(targetMethodName + "is invoked..");
}
}
'Archived(Programming) > Spring #2(기초)' 카테고리의 다른 글
트랜잭션과 로깅 (0) | 2020.03.18 |
---|---|
PointCut 표현식과 Advisor 구현 (0) | 2020.03.17 |
Dynamic SQL (0) | 2020.03.17 |
Mapper XML 파일 (1) | 2020.03.16 |
Spring Mybatis (0) | 2020.03.15 |