스프링 AOP(Aspect Oriented Programming)

HyeonWoo·2020년 12월 22일
1

스프링 & JPA

목록 보기
16/34
post-thumbnail

이번 장에서는 스프링 AOP의 정의와 주요용어, 특징에 대해서 알아보고자 한다.


스프링 AOP(Aspect Oriented Programming)이란?

관점 지향 프로그래밍 : 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어서 보고 그 관점을 기준으로 각각 모듈화 하는 것.

*모듈화 : 어떤 공통된 로직이나 기능을 하나의 단위로 묶는것 ( 모듈화 -> 코드 반복x )

*핵심적인 관점 : 구현하고자하는 핵심 비즈니스 로직(유저 눈에 보이진 않지만, 유저가 바라는 결과물을 올바르게 도출하기 위해 짜는 코드)

*부가적인 관점 : 핵심 로직을 실행하기 위해서 행해지는 데이터베이스 연결, 로깅, 파일 입출력 등등.

위의 사진을 보면 빨간색 파란색 주황색 동일한 코드들이 A,B,C 클래스에서 중복되어 사용되고 있다. 이러한 코드들을 흩어진 관심사(Crosscutting Concerns)라 부른다.
화살 표 아래처럼 흩어진 관심사를 Aspect로 모듈화하고 핵심적인 비즈니스 로직에서 분리하여 재사용하겠다는것이 AOP의 취지이다.

간단한 코드를 통하여 aop의 개념을 정리하자면

class A {
 
    method a() {
        AAAA //부가적인 관점 
 
        method a가 하는 일들 //핵심적인 관점
 
        BBBB //부가적인 관점
    }
 
    method b() {
        AAAA
 
        method b가 하는 일들
 
        BBBB
    }
}
 
class B {
    method c() {
        AAAA
 
        method c가 하는 일들
 
        BBBB
    }
}

위와 같은 코드는 부가적인 관점인 코드들이 변경이 필요한 경우 일일이 다 찾아서 바꿔줘야하는 단점이 있다.
하지만 AOP는 여러군데서 사용하고 있는 중복된 코드를 떼어내서 분리하고, 각 메소드 a,b,c 는 자신이 해야할 작업(핵심적인 관점)만 갖고 있자는 개념이다.


AOP 주요 용어

  • Aspect: 흩어진 관심사를 모듈화 한 것. 주로 부가 기능을 모듈화
  • Target: Aspect을 적용하는 곳 ( 클래스나 메소드 )
  • Adivce: 실직적으로 어떤 일을 해야할 지에 대한 것, 실질적인 부가기능을 담은 구현체
  • JointPoint : Advice가 적용될 위치, 끼어들 수 있는 지점, 메서드 진입 지점, 생성자 호출 시점, 필드에서 값을 꺼내올 때 등 다양한 시점에서 적용가능
  • PointCut : JointPoint의 상세한 스펙을 정의한 것. 'A란 메서드의 진입 시점에 호출할 것'과 같이 더욱 구체적으로 Advice가 실행될 지점을 정할 수 있음.

스프링 AOP 특징

  • 모든 AOP 기능을 제공하는 것이 아닌 스프링 IOC와 연동하여 엔터프라이즈 애플리케이션에서 가장 흔한 문제(중복 코드, 프록시 클래스 작성의 번거로움, 객체들 간 관계 복잡도 증가)에 대한 해결책을 지원하는 것이 목적.

  • 프록시 패턴 기반의 AOP 구현체

  • 스프링 빈에서만 AOP 적용 가능

*프록시 패턴 : 실제 기능을 수행하는 객체 대신 가상의 객체를 사용해 로직의 흐름을 제어하는 디자인 패턴.

AOP 관련 어노테이션

스프링 AOP를 사용하기 위해서는 의존성을 추가해야 한다.

implementation 'org.springframework.boot:spring-boot-starter-aop'

@Component
@Aspect
public class AopTests{

     // com.saelobi 아래의 패키지 경로의 EventService 객체의 모든 메서드에 이 Apsect를 적용하겠다라는 의미.
	@Around("execution(* com.saelobi..*.EventService.*(..))")
	public Object kbs(ProceedingJoinPoint joinPoint) throws Throwable{

		String methodName = joinPoint.getSignature().toString(); //핵심 메소드명 얻기

		System.out.println(methodName + " 시작 전 작업....");

		Object object = joinPoint.proceed(); //핵심 메소드

		System.out.println(methodName + " 종류 후 작업....");
        
		return object;

	}
	// @Before : @Before 어노테이션에 명시된 메소드 실행전만 처리할 경우 사용

	@Before("execution(* com.saelobi..*.EventService.*(..))")

	public void before(){

		System.out.println("메소드 실행 전 @Before");

	}

	// @After : @After 어노테이션에 명시된 메소드 실행후만 처리할 경우 사용

	@After("execution(* com.saelobi..*.EventService.*(..))")

	public void after(){

		System.out.println("메소드 실행 후 @After");

	}

}

참고자료
https://engkimbs.tistory.com/746,
https://tibang.tistory.com/entry/AOP-%EA%B5%AC%ED%98%84%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%953-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EB%B0%A9%EB%B2%95

profile
학습 정리, 자기 개발을 위한 블로그

0개의 댓글