본문 바로가기
WEB/✿Spring Framework

[Spring] 🔗3) AOP

by W_W_Woody 2022. 2. 25.

스프링 AOP(Aspect Oriented Programming)

AOP(Aspect Oriented Programming)는 로깅과 같은 기본적인 기능에서부터 트랜잭션이나 보안과 같은 기능에 이르기까지 어플리케이션 전반에 걸쳐 적용되는 공통기능을 핵심 기능과 분리해서 모듈로 구현한 뒤 핵심 기능이 수행될 때 필요로 하는 곳에 공통기능이 적용되게 하는 기능이다. 공통의 관심사항을 적용해서 발생하는 의존 관계의 복잡성과 코드 중복을 해소해 주는 프로그래밍 기법이다.


하나의 파일에

1.     내용들을 콘솔에 기능 출력 =>공통기능(로그처리, 보안, 트랜잭션처리)

2.     핵심기능(고유기능)이 동작

3.     로그 출력 => 공통기능

공통기능이 변경될 경우 파일을 다 열어서 수정해야하므로 유지 보수 기능이 떨어진다.

그래서 AOP가 나왔다. (관점지향프로그래밍)

일반프로그램에는 AOP가 적용되어있지않다.

공통기능을 별도로 뽑아내고, 핵심기능만 있는 파일을 만들어낸다. (공통기능과 핵심기능을 분리)

 

공통기능을 원하는 시점에 결합시킨다

( 공통기능(로그처리, 보안, 트랜잭션처리)을 핵심기능 전에 적용할 것인지, 후에 적용할 것인지)

 

AOP기능을 이용해서 핵심기능을 검색할 수도 있다.

핵심기능이 반환타입을 항상 갖는게아니라 void형 일 수도 있다.


Aop 사용할때는 라이브러리 추가해야 에러안난다.

Pom.xml에 추가한다.

 

-  AOP 용어

Advice 언제 공통 관심 기능을 핵심 로직에 적용할 지를 정의. 
Joinpoint Advice를 적용 가능한 지점을 의미. 메서드 호출, 필드 값 변경 등이 Joinpoint에 해당
Pointcut Joinpoint의 부분 집합으로서 실제로 Advice가 적용되는 Joinpoint를 나타냄. 
Weaving Advice를 핵심 로직 코드에 적용하는 것을 weaving이라고 함.
Aspect 여러 객체에 공통으로 적용되는 공통 관심 사항

- 세 가지 Weaving 방식

  • 컴파일 시점에 코드에 공통 기능을 추가하는 방법 (스프링 기본 지원이 아니며 AspectJ와 같이 AOP를 위한 전용 도구를 사용해야 함)
  • 클래스 로딩 시점에 바이트 코드에 공통 기능을 추가하는 방법 (스프링 기본 지원이 아니며 AspectJ와 같이 AOP를 위한 전용 도구를 사용해야 함)
  • 런타임에 프록시 객체를 생성해서 공통 기능을 추가하는 방법 (스프링이 제공하는 AOP 방식)

- 스프링에서의 AOP

  • XML 스키마 기반의 POJO 클래스를 이용한 AOP 구현
  • @Aspect 어노테이션 기반의 AOP 구현

- 구현 가능한 Advice 종류

종류 설명
Before Advice 대상 객체의 메서드(핵심기능) 호출 전에 공통기능을 실행
After Returning Advice 대상 객체의 메서드가 예외 없이 실행한 이후에 공통 기능을 실행
After Throwing Advice 대상 객체의 메서드를 실행하는 도중 예외가 발생한 경우에 공통 기능을 실행
(예외가 발생했을 경우에만 등장)
After Advice 대상 객체의 메서드를 실행하는 도중에 예외가 발생했는지의 여부와 상관없이 메서드 실행 후 공통 기능을 실행. 
(try~catch~finally의 finally블럭과 비슷)
Around Advice 대상 객체의 메서드 실행 전, 후 또는 예외 발생 시점에 공통 기능을 실행하는데 사용

 

XML 스키마를 이용한 AOP 설정

AspectJ의 Pointcut 표현식 (핵심기능을 검색하는 방법) 

<aop:aspect id="traceAspect1" ref="performanceTraceAdvice">
<aop:pointcut expression="execution(public * com.spring.board..*(..))" id="publicMethod"/>
<aop:around method="trace" pointcut-ref="publicMethod"/>
</aop:aspect>

 

execution 명시자는 Advice를 적용할 메서드를 명시할 때 사용됨

execution(식어패턴 리턴타입패턴 클래스이름패턴 이름패턴(파라미터패턴)

예)

- execution(public void set*(..))
리턴 타입이 void이고 메서드 이름이 set으로 시작하고, 파라미터가 0개 이상인 메서드 호출
- execution(* com.spring.ch01.*.*()) //패키지.클래스.메서드
com.spring.ch01 패키지의 파라미터가 없는 모든(*) 메서드 호출
- execution(* com.spring.ch01..*.*(..)) //..하위패키지까지 확장
com.spring.ch01 패키지 및 하위 패키지에 있는 파라미터가 0개 이상인 메서드 호출
- execution(Integer com.spring.ch01..WriteArticleService.write(..))
리턴 타입이 Integer인 kr.spring.ch01 패키지 및 하위 패키지의 WriteArticleService 인터페이스의 write() 메서드 호출
- execution(* get*(*))
이름이 get으로 시작하고 1개의 파라미터를 갖는 메서드 호출
- execution(* get*(*,*))
이름이 get으로 시작하고 2개의 파라미터를 갖는 메서드 호출
- execution(* read*(Integer,*))
메서드 이름이 read로 시작하고, 첫 번째 파라미터 타입이 Integer이며, 1개 이상의 파라미터를 갖는 메서드 호출
<!-- Aspect 설정 : Advice를 어떤 Pointcut에 적용할지 설정 -->
<aop:config>
<aop:aspect id="traceAspect1" ref="performanceTraceAdvice">
<aop:pointcut expression="execution(public * com.spring.board..*(..))" id="publicMethod"/>
<aop:around method="trace" pointcut-ref="publicMethod"/>
</aop:aspect>
</aop:config>


<bean id="writeArticleService" class="com.spring.board.service.WriteArticleServiceImpl">
<constructor-arg>
<ref bean="articleDao"/>
</constructor-arg>
</bean>
<bean id="articleDao"  class="com.spring.board.dao.WriteArticleDao"/>

 

Advice 정의 관련 태그

종류 설명
<aop:before> 메서드 실행 전에 적용되는 Advice를 정의한다.
<aop:after-returning> 메서드 정상적으로 실행된 후에 적용되는 Advice를 정의한다.
<aop:after-throwing> 메서드가 예외를 발생시킬 때 적용되는 Advice를 정의한다. try-catch블록에서 catch 블록과 비슷하다.
<aop:after> 메서드가 적상적으로 실행되느니지 또는 예외를 발생시키는지 여부에 상관없이 적용되는 Advice를 정의한다.
try-catch-finally에서 finally 블록과 비슷하다. 
<aop:around> 메서드 호출 이전, 이후, 예외 발생 등 모든 시점에 적용 가능한 Advice를 정의한다.
Around Advice를 설정함
<aop:config> AOP 설정 정보임을 나타냄
<aop:aspect>  Aspect를 설정함
<aop:pointcut> Pointcut을 설정함

 

@Aspect 어노테이션을 이용한 AOP

<!-- 어노테이션 방식으로 AOP를 구현할 경우 명시해야할 것 -->
<aop:aspectj-autoproxy/>

 

@Aspect
public class ProfilingAspect {


@Pointcut("execution(public * com.spring.board..*(..))")
private void profileTarget(){}


@Around("profileTarget()")
public Object trace(ProceedingJoinPoint joinPoint)
                                  throws Throwable{

종류 설명
Before Advice
@Before
대상 객체의 메서드(핵심기능) 호출 전에 공통기능을 실행
After Returning Advice
@AfterReturning
대상 객체의 메서드가 예외 없이 실행한 이후에 공통 기능을 실행
After Throwing Advice
@AfterThrowing
대상 객체의 메서드를 실행하는 도중 예외가 발생한 경우에 공통 기능을 실행
(예외가 발생했을 경우에만 등장)
After Advice
@After
대상 객체의 메서드를 실행하는 도중에 예외가 발생했는지의 여부와 상관없이 메서드 실행 후 공통 기능을 실행. 
(try~catch~finally의 finally블럭과 비슷)
Around Advice
@Around
대상 객체의 메서드 실행 전, 후 또는 예외 발생 시점에 공통 기능을 실행하는데 사용

'WEB > ✿Spring Framework' 카테고리의 다른 글

[Spring] 🔗6) 로깅처리  (0) 2022.03.05
[Spring] 🔗4) Spring MVC  (0) 2022.02.25
[Spring] 🔗1) IoC컨테이너(Spring 컨테이너)  (0) 2022.02.24
[Spring] 🔗Spring Framework  (0) 2022.02.24
[Spring] 🔗basic  (0) 2022.02.22

댓글