스프링 AOP

정권호·2022년 1월 2일
0

Spring

목록 보기
2/2
post-thumbnail

AOP란?

Aspect-oriendted Programming (AOP)은 OOP를 보완하는 수단으로, 흩어진 Aspect를 모듈화 할 수 있는 프로그래밍 기법.

Concerns란?

클래스들 안에 반복적으로 나타나는 비슷한 코드들

가장 보편적인 예제는 트랜잭션과 로깅

ex) 트랜잭션
AutoCommit false -> Query 실행 -> Commit or RollBack

ex) 성능관련 로깅
메소드 시작 지점 시간체크 -> 메소드 끝 지점 시간체크

다음과 같은 형태로 다른 클래스이지만 비슷한 기능들.


AOP 주요 개념

Target

Advice가 적용되는 대상 객체 (클래스)
Pointcut의 상위 느낌으로 Target -> 클래스, PointCut -> 메소드

Aspect

흩어진 관심사들을 모아서 모듈화 한것
Advice + PointCut

Advice

해야할 일 -> 실행하는 코드

Pointcut

Advice가 적용되는 대상 (메소드)

Join Point

Advice가 실행되는 시점 -> 끼어드는 지점, 합류되는 지점
ex) 메소드 실행시점(가장 흔히 사용되는)


AOP 적용 방법

컴파일

컴파일 타임에 적용하여 바이트 코드에 같이 적용

  • 장점: 로드타임과 런타임때 성능 부하 없음
  • 단점: 별도의 컴파일 과정이 필요

로드 타임

클래스르 로딩하는 시점 (컴파일은 순수히 클래스 파일만)

  • 장점: 다양한 문법 사용가능
  • 단점: 클래스 로딩할때 부하, 로드타임 위버 설정 필요(로드타임의 자바 에이전트 설정 필요)

런타임

스프링 AOP가 사용하는 방법, 프록시 기반
A라는 빈을 만들때, A를 감싸는 프록시 빈을 생성

  • 장점: 아무런 설정 필요X, 문법이 쉬움
  • 단점: 빈 생성시에 성능 부하(로드타임과 유사한 부하)

스프링 AOP 특징

  • 프록시 기반 aop
  • 스프링 빈에만 적용
  • 모든 AOP 기능을 뿐만이 아닌 스프링 IoC와 연동하여 엔터프라이즈 애플리케이션에서 가장 흔한 문제에 대한 해결책을 제공

프록시 패턴

프록시 패턴은 다음과 같은 형태로 클라이언트에게 실제 객체가 아닌 프록시 객체를 제공하는 패턴이다.

public interface Subject {
	void doAction();
}
// 실제 객체
@Service
public class RealSubject implements Subject{

	@SneakyThrows
	@Override
	public void doAction() {
		Thread.sleep(1000);
		System.out.println("do something...");
	}
}
// 프록시 객체 (@Primary로 같은 타입의 빈이 있으면 해당 타입으로 주입)
@Primary
@Service
@RequiredArgsConstructor
public class Proxy implements Subject{
	private final RealSubject realSubject;

	@Override
	public void doAction() {
		long now = System.currentTimeMillis();
		realSubject.doAction();
		System.out.println("실행시간: " + (System.currentTimeMillis() - now));
	}
}

이와 같은 형태로 실제 객체를 감싼 형태로 부가 기능을 추가하여 프록시 객체를 생성하고


@Component
@RequiredArgsConstructor
public class AppRunner implements ApplicationRunner {
	// 프록시 객체가 주입됨
	private final Subject subject;

	@Override
	public void run(ApplicationArguments args) {
		subject.doAction();
	}
}

실제로 실행을 하면 다음과 같이 부가 기능(시간 체크)이 정상적으로 작동한다.
이렇게 프록시 객체는 실제 객체를 감싸고 있는 형태로 객체를 제공함으로써 기존의 코드를 건드리지 않고 접근 제어 또는 부가기능이 추가 가능해진다.


프록시 패턴의 문제점

  • 매번 프록시 클래스를 작성해야한다.
  • 여러 클래스 여러 메소드에 적용하면 결국 중복코드가 발생한다.
  • 객체들의 관계가 복잡해지면?
  • 그래서 등장한 것이 스프링 AOP

스프링 AOP

스프링 IoC 컨테이너가 제공하는 기반 시설과 동적 프록시를 사용하여 여러 복잡한 문제 해결
(어너테이션으로 간단하게 적용 가능, 적용법은 다음 기회에...)

동적 프록시

동적으로(런타임에) 프록시 객체 생성하는 방법

  • CGlib은 클래스 기반 프록시도 지원.
  • 자바가 제공하는 방법은 인터페이스 기반 프록시 생성.

스프링 IoC

스프링 IoC: 기존 빈을 대체하는 동적 프록시 빈을 만들어 등록 시켜준다.

  • 클라이언트 코드 변경 없음.
  • AbstractAutoProxyCreator implements BeanPostProcessor -> 이 클래스가 프록시 빈을 생성해준다.
profile
머라도 해봐요

0개의 댓글