AOP란?
- Aspect Oriented Programming: 관점 지향 프로그래밍
- 여러 객체에서
공통적으로 사용하고 있는 기능을 분리해서 모듈화하고 재사용
하는 프로그래밍 기법
- 핵심 기능과 공통 기능의 구현을 분리하여 핵심 기능의 코드 수정없이 공통 기능 적용 가능
- 여러 클래스, 메소드에 공통적으로 나타나는 코드들을
Concern
이라고 한다.
- 각 클래스에 있는 Crosscutting Concerns(흩어진 관심사)를 Aspect로 모듈화하고 핵심적인 비즈니스 로직에서 분리하여 재사용하겠다는 것이 AOP의 취지이다.
- AOP는 AOP의 구현체를 제공하며, 자바에 만들어져 있는 프레임워크 AspectJ라는 또 다른 구현체와 연동해서 사용할 수 있는 기능을 제공한다.
- 대표적으로 인증, 트랜잭션 관리, 로깅 등과 같은 인프라 로직을 AOP로 처리한다.
- 스프링은 프록시 기반 AOP를 지원한다.
각각의 색들을 Concern이라고 보면된다.
여기서 Concern이란 여러 클래스, 메서드에 걸쳐서 나타나는 비슷한 코드들을 의미한다.
각 클래스에 있는 Crosscutting Concerns, 흩어진 관심사를 Aspect로 모듈화하고 핵심적인 비즈니스 로직에서 분리하여 재사용하겠다는 것이 AOP의 취지이다.
AOP 적용방식
- 컴파일 시점에 코드에 공통기능을 삽입
- AOP 개발도구가 소스 코드를 컴파일 하기 전에 공통 구현 코드를 소스에 삽입하는 방식
- AspectJ같은 AOP 전용도구를 사용해서 적용
- 클래스 로딩 시점(로드 타임)에 바이트 코드에 공통 기능을 삽입
- 클래스를 로딩할 때 바이트 코드에 공통 기능을 클래스에 삽입하는 방식
- AspectJ 같은 AOP 전용 도구를 사용해서 적용
- 런타임에 프록시 객체를 생성해서 공통 기능을 삽입
- 프록시 객체를 생성하고 그 안에 실제 객체를 넣어 실제객체를 통해 핵심기능을 실행하고 공통 기능은 프록시 객체가 처리하는 방식
- 스프링 AOP에서 지원
- 스프링 AOP가 프록시 객체를 자동으로 생성하여 처리해주기 때문에 프록시 클래스를 직접 구현할 필요가 없다.
- 개발자는 공통 기능을 구현한 클래스만 구현하면 된다.
Spring AOP 특징
프록시 패턴 기반
의 AOP 구현체
- Target 객체에 대한 프록시를 만들어 제공
- Target을 감싸는 프록시는 런타임 시 생성
- 접근 제어 및 부가 기능 추가를 위해 프록시 객체 사용
- 프록시가 Target 객체의 호출을 가로채 Advice 수행 전/후 핵심 로직 호출
- 스프링 Bean에만 AOP 적용 가능
- 메소드 조인 포인트만 지원하여 메소드가 호출되는 런타임 시점에만 Advice 적용 가능
- 모든 AOP기능을 제공하지는 않으며 스프링 IoC와 연동하여 엔터프라이즈 애플리케이션의 각종 문제(중복 코드, 프록시 클래스 작성의 번거로움, 객체 간 관계 복잡도 증가)에 대한 해결책 지원 목적
AOP 프록시 동작방식
프록시 패턴
프록시 패턴에는 interface
가 존재하고 Client는 이 interface 타입으로 Proxy 객체를 사용하게 된다.
Proxy 객체는 기존의 타겟 객체(Real Subject)를 참조하고 있다. Proxy 객체와 Real Subject의 타입은 같고, Proxy는 원래 해야 할 일을 가지고 있는 Real Subject를 감싸서 Client의 요청을 처리한다.
AOP 용어
Aspect(관점, 관심)
- 여러 객체에 공통으로 적용되는 기능
@Transactional
이나 @Cacheable
, 보안 등이 좋은 예
- 클래스 단위에서
@Aspect
로 적용
- Aspect 클래스 내부에는 Advice와 Point Cut이 들어간다.
Advice(조언)
- AOP에서 실제로 적용하는 기능
- 언제 공통 관심 기능을 핵심 로직에 적용할지를 정의
- 실제로 적용할 기능을 작성한다.
- 어노테이션에는 포인트컷을 알려줘야한다.
Before
- 대상 객체의 메서드 호출 전에 공통 기능을 실행
After Returning
- 대상 객체의 메서드가 익셉션 없이 실행된 이후에 공통기능을 실행
After Throwing
- 대상 객체의 메서드를 실행하는 도중 익셉션이 발생한 경우에 공통기능을 실행
After
- Exception 발생여부에 상관없이 대상객체의 메서드 실행 후 공통 기능 실행
- try - catch -finally 에서 finally 와 유사
Around
- 대상 객체 메서드 실행하기 전/후 , 익셉션 발생 시점 등 다양한 시점에 공통 기능 실행
Joinpoint(연결 포인트)
- Advice를 적용될 위치, 끼어들 수 있는 지점
- 생성자 호출 직전, 생성자 호출 시, 필드에 접근하기 전, 필드에서 값을 꺼낼 때 등
- 스프링은 프록시를 이용해서 AOP를 구현하기 때문에 메서드 호출에 대한 Joinpoint만 지원한다.
Pointcut (포인트 선택방법)
- 실제
Advice가 적용되는
Joinpoint
- Joinpoint 중에서 해당
Aspect를 적용할 대상을 뽑을 조건식
- 스프링에서는 정규표현식이나 AspectJ의 문법을 이용하여 Pointcut을 정의할 수 있다.
- 여러 Aspect에서 공통으로 사용하는 Pointcut이 있다면 별도 클래스로 분리하는 것이 좋다.
Target Object
- Advice가 적용될 대상(클래스, 메소드 등)
AOP Proxy
- 대상 오브젝트에 Aspect를 적용하는 경우, Advice를 덧붙이기 위해 하는 작업을 의미
- 주로 CGLIB(Code Generation Library, 실행 중에 실시간으로 코드를 생성하는 라이브러리) 프록시를 사용하여 프록싱 처리한다.
Weaving
📚참고
스프링 AOP 총정리
Spring AOP(관점 지향 프로그래밍)
Spring:스프링AOP란? Aspect Oriented Programming