programming/Spring & WEB

Spring) AOP 개념 및 설정 + 예제

코딩하는 핑가 2021. 1. 26. 15:22
반응형

* 이 포스팅은 atoz-develop.tistory.com/ , shlee0882.tistory.com/, engkimbs.tistory.com/ 님의 포스팅을 학습한 뒤 추가로 공부한 후 재정리한 글입니다.

* 해당 개념을 완벽하게 이해하지 못해 설명이 다소 미흡할 수 있습니다. 참고만 해주세요.

* 2차 가공 및 재배포를 금지합니다. ( 재배포시 출처를 남겨주세요 )

* 오탈자 및 잘못된 내용은 댓글달아주세요.

 

1. AOP의 개념

* AOP ( Aspect Oriented Programming )

- 관점 지향 프로그래밍

- 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어보고 그 관점을 기준으로 각각 모듈화하겠다.

모듈화 : 어떤 공통된 로직이나 기능을 하나의 단위로 묶는 것
핵심적인 관점 ( Core Concerns ) : 업무 로직을 포함하는 기능 ( 우리가 적용하고자 하는 핵심 비즈니스 로직 )
부가적인 관점 ( Cross-cutting Concerns ) : 핵심 기능을 도와주는 부가적인 기능 ( 핵심 로직을 실행하기 위해서 행해지는 데이터베이스 연결, 로깅, 파일 입출력 등 )

출처 : https://shlee0882.tistory.com/206

- AOP에서 각 관점을 기준으로 로직을 모듈화 한다는 것은 코드들을 부분적으로 나누어서 모듈화한다는 것

- 이때, 소스 코드 상에서 다른 부분에 계속 반복해서 쓰는 코드들을 발견할 수 있는데 이것을 흩어진 관심사(Crosscutting Concerns)라 부름

 

자세히 들어가기 전, 객체 지향 프로그래밍과의 차이점을 먼저 살펴보자.

 

1-2. OOP의 개념

* OOP ( Object Oriented Programming )

- 객체 지향 프로그래밍

- 모든 변수 선언 시 new를 통해서 객체를 선언하는 스몰토크의 불편한 점을 개선한 언어

- 객체를 재사용함으로써 개발자들은 반복되는 코드의 양을 굉장히 많이 줄일 수 있었다.

- 하지만 객체를 재사용함에도 불구하고 반복되는 코드를 없앨 수 없었다.

- 객체 지향 프로그래밍은 핵심기능에서 부가기능을 분리해서 모듈화하는 작업이 매우 어려움

반복되는 코드 : 로그, 권한 체크, 인증, 예외 처리 등 필수적으로 해야하는 소스들

즉, OOP의 로직 흐름 상 핵심기능과 부가기능을 분리해서 모듈화하는 것이 어려운 문제점을 해결해주기 위해 AOP를 사용함

 

 

2. AOP 로직 흐름

출처 : https://engkimbs.tistory.com/746

위와 같이 흩어진 관심사를 Aspect로 모듈화하고 핵심적인 비즈니스 로직에서 분리하여 재사용한다.

 

[ 간단한 소스 코드로 AOP 살펴보기 ]

class A {
	method a() {
    	AAAA
        
        method a가 하는 일들
        
        BBBB
    }
    
    method b() {
    	AAAA
        
        method b가 하는 일들
        
        BBBB
    }
}

class B {
	method c() {
    	AAAA
        
        method c가 하는 일들
        
        BBBB
    }
}

위와 같이 동일한 일을 하는 코드 AAAA, BBBB가 여기저기서 사용되고 흩어져있으면 코드 변경이 필요한 경우 하나씩 다 찾아서 바꿔야 한다.

AOP는 중복되는 코드를 떼어내서 분리하고 method a,b,c는 자신이 해야할 작업만 갖고 있자는 개념이다.

- 여러군데서 사용되는 중복되는 코드 : AOP에서 말하는 aspect

- AOP는 부가기능을 애스펙트(Aspect)로 정의하여, 핵심기능에서 부가기능을 분리함으로써 핵심기능을 설계하고 구현할 때 객체지향적인 갈치를 지킬 수 있도록 도와줌

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

 

3. AOP 특징

* 프록시 패턴 기반

- spring은 타겟(target) 객체에 대한 프록시를 만들어서 제공

- 타겟을 감싸는 프록시는 실행시간(runtime)에 생성

- 프록시는 어드바이스를 타켓 객체에 적용하면서 생성되는 객체

- 프록시 객체를 쓰는 이유는 접근 제어 및 부가기능을 추가하기 위함

 

* 프록시가 호출을 가로챔(Intercept)

- 프록시는 타겟 객체에 대한 호출을 가로챈 다음 어드바이스의 부가기능 로직을 수행하고 난 후에 타겟의 핵심기능 로직을 호출함 ( 전처리 어드바이스 )

- 타겟의 핵심기능 로직 메서드를 호출한 후에 부가기능(어드바이스)을 수행하는 경우도 있다.(후처리 어드바이스)

 

* 메서드 조인 포인트만 지원

- Spring은 동적 프록시를 기반으로 AOP를 구현하므로 메서드 조인 포인트만 지원

- 핵심기능(타겟)의 메서드가 호출되는 런타임 시점에만 부가기능(어드바이스)을 적용할 수 있음

 

- 반면에 AspectJ같은 고급 AOP 프레임워크를 사용하면 객체의 생성, 필드값의 조회와 조작, static 메서드 호출 및 초기화 등의 다양한 작업에 부가기능을 적용할 수 있음

 

* 프록시 패턴
- 어떤 기능을 추가하려 할 때 기존 코드를 변경하지 않고 추가 가능
- 어떤 클래스가 String AOP의 대상이라면 그 기존 클래스의 빈이 만들어질 때 Spring AOP가 프록시(기능이 추가된 클래스)를 자동으로 만들고 원본 클래스 대신 프록시 빈으로 등록
- 그리고 원본 클래스가 사용되는 지점에서 프록시를 대신 사용
* 스프링 빈
- Spring IoC 컨테이너가 관리하는 자바 객체를 빈(Bean)이라는 용어로 부름
- 우리가 new 연산자로 어떤 객체를 생성했을 대 그 객체는 빈이 아니다.
- ApplicationContext.getBean()으로 얻어질 수 있는 객체는 빈이다.
- 즉 Spring에서의 빈은 ApplicationContext가 알고 있는 객체, 즉 ApplicationContext가 만들어서 그 안에 담고 있는 객체를 의미

 

4. AOP 주요 키워드

* Target

- 핵심 기능을 담고 있는 모듈

- 어떤 관심사들과도 관계를 맺지 않음

- Aspect를 적용하는 곳 ( 클래스, 메서드 )

 

* Aspect

- 흩어진 관심사를 모듈화한 것 ( 여러 핵심 기능에 적용될 관심사 모듈 )

- 구체적인 기능을 구현한 Advice와 Advice가 어디에서 적용될지를 결정하는 PointCut을 포함

- AOP의 기본 모듈- 싱글톤 형태의 객체로 존재

 

* Advice

- 타겟에 제공할 부가기능을 담고 있는 모듈 ( 실질적인 부가기능을 담은 구현체 )

- 실질적으로 어떤 일을 해야할 지에 대한 것

- Aspect가 무엇을 언제 적용할지를 정의

 

* PointCut

- 공통 기능이 적용될 대상 결정

- 어드바이스를 적용할 타겟의 메서드를 선별하는 정규표현식

- JoinPont의 상세한 스펙을 정의한 것

- execution으로 시작하고 메서드의 Signature를 비교하는 방법을 주로 이용

 

* JoinPont

- Advice가 적용될 위치, 끼어들 수 있는 지점

- 타겟 객체가 구현한 인터페이스의 모든 메서드는 조인 포인트가 됨

- 메서드 진입 지점, 생성자 호출 시점, 필드에서 값을 꺼내올 때 등 다양한 시점에 적용 가능

 

* Advisor

- Advice + Pointcut

- Spring AOP에서만 사용되는 용어

 

* Weaving

- 포인트컷에 의해서 결정된 타겟의 조인 포인트에 부가기능(어드바이스)를 삽입하는 과정

- AOP가 핵심기능(타겟)의 코드에 영향을 주지 않으면서 필요한 부가기능(어드바이스)를 추가할 수 있도록 해주는 핵심적인 처리과정

 

5. 구현 방식

* XML 기반의 POJO 클래스를 이용한 AOP 구현

- 부가기능을 제공하는 Advice 클래스를 작성

- XML 설정 파일에 <aop:config>를 이용해서 애스펙트를 설정

- 즉, 어드바이스와 포인트컷을 설정

 

* @Aspect 어노테이션을 이용한 AOP 구현

- @Aspect 어노테이션을 이용해서 부가기능을 제공하는 Aspect 클래스를 작성

- 이 때, Aspect 클래스는 어드바이스를 구현하는 메서드와 포인트컷을 포함

- XML 설정 파일에 <aop:aspectj-autoproxy />를 설정

 

6. 설정

* m.blog.naver.com/gidiun/220700341118

 

ASPECTJ 설정 및 기본적인 예제 만들기

안녕하세요 흰까마귀 입니다.오늘은 ASEPCTJ 설정 및 간단한 기본예제를 구현해보겠습니다 1) http:...

blog.naver.com

 

7. 기본 예제

[ HelloAop.java ]

public class HelloAop {

	public static void main(String[] args) {
		new HelloAop().sayHello("test");
	}
	
	private void sayHello(String msg){
		System.out.println(msg);
	}

}

 

[ HelloMessage.aj ]

public aspect HelloMessage {
	pointcut helloCall(): call(* HelloAop.sayHello(..));
	
	before(): helloCall(){
		System.out.println("before");
	}
	
	after():helloCall(){
		System.out.println("around");
	}

}

 

[ 결과 ]

before
test
around
반응형