본문 바로가기

개발자노트/Spring

AOP 용어 정리

[관점지향 프로그래밍]
Aspect Oriented Programing

AOP에서는 핵심로직에서 직접 공통관심을 호출하지 않고

위빙(Weaving)이라 불리는 작업을 해서 공통관심 기능 코드를 주입

이러한 위빙작업을 하기 위해서는 어디에(Pointcut), 언제(Advice) 주입을 해야할지 알아야한다.

 

1) Pointcut (포인트컷 , 어디에 )

어디에 공통관심 기능코드를 주입할 것인지 정의한다.

횡단관심을 적용할 핵심로직을 의미한다.

하나의 @Aspect 안에 여러개의 포인트 컷을 선언할 수도 있다.

 

 

2) aspect  (결합)

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

비즈니스 메서드가 시작/ 끝나면 그때 등록해둔 advice가 실행 → 스프링 컨테이너가 담당 및 관리 

 

advice : 결합시기

어드바이스도 포인트컷과 마찬가지로 하나 이상을 정의할 수 있다.

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

asepct가 무엇을 언제 적용할지를 정의한다.


 - <aop:after> 비즈니스 메서드 사용 후에 수행한다.
 - <aop: after-returning> : 핵심로직의 반환값을 가지고서 무언가 처리할 때 사용한다.
 - <aop: after-throwing> :  예외처리에 대한 것을 수행해야할 때 사용한다.
 - <aop:before> 비즈니스 메서드 사용 전에 사용한다.
 - <aop:around> 를 사용할 advice는 반드시 pjp를 input으로 가져아한다.

1. 로직을 사용하기 위한 com.kim.biz.common.LogAdvice 경로의 클래스 객체를 id="logAdvice" 로 bean 생성

 

2. 횡단관심을 적용할 핵심로직을 지정해주는 pointcut  , id ="부르게될이름"

expression(표현식)에 어떤 핵심로직인지 알려줘야함 ( 어떤 대상인지 알려줌 ) 

excution(* com.kim.biz..*Impl.*(..))   → ( [ * ] [클래스명.메서드명] [(..)]  , 메서드 시그니처와 유사하다) 

[*] = 모든 output[클래스명.메스드명] = com.kim.biz..*Impl.* = com.kim.biz 경로 하위 .. 에 있는 모든 클래스 중

(*)Impl로 끝나는 클래스의 메서드의 모든것 .*

[(..)] = Input 은 없을 수도 있고, 여러개 일 수도 있어서 모든 갯수를 받을 수 있도록 설정

 

3. logAdvice 객체가 어떤 alphaPointcut에  method를 수행할 지 설정

 

 

즉, 모든 비즈니스로직에 대한 pointcut인 alphaPointcut이  <aop:before>에 의해, 

비즈니스로직이 수행되기 전에, method=printLog 가 수행된다.

 

LogAdvice 의 printLog 메서드

실질적으로 메서드는 Service에서 사용되기 때문에, BoardService를 implements 하는 BoardServiceImpl에서

비즈니스 메서드를 사용할 때, LogAdvice의 printLog()가 호출되도록 하는 것이다.

 

 

출력결과

내용작성 >> 후 insertBoard() 이 되기전에 LogAdvice가 출력되었고,

SelectAll() 이 수행되기 전에, LogAdvice가 출력된 것을 볼 수 있다.

 

 

 

 

 

🔴 xml에 AOP 설정하는 방법!

 

1. Spring Bean Configuration File을 만든다.

✔ 중요한점!

파일의 확장자를 .xml 로 저장하게되면 , Spring Bean Configuration의 형식을 가지고 있는 xml 파일로 저장이 됨!

생성 후 파일을 열어보면 , 하단에 Namesapces 탭을 누르게 되면 상단과 같은화면이 나오는데 이 때 aop를 체크!

 

파일 내부에 다음과 같이 aop schema 가 추가된 것을 볼 수 있다.

 

 

AOP.xml 예시코드 ( 사용할 때 주석을 지워야 정상작동을 한다 )

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">

	<context:component-scan base-package="com.kim.biz" />
	
	<bean id="LogAdvice" class="com.kim.biz.common.LogAdvice" />
	<aop:config> <!-- aop 설정 --> 
	  <aop:pointcut expression="execution(* com.kim.biz..*Impl.*(..))" id="aPointcut"/>
	  								<!-- 어떤 핵심관심을 사용할지 -->
	  <aop:aspect ref="LogAdvice">
	  		<aop:around method="printLog" pointcut-ref="aPointcut"/> <!-- aop 까지만 쳐보고 자동완성을 보면 언제 넣을지 선택 가능 -->
	  		 <!-- 어떤 로직을 사용할지(로직명) -->	<!-- 어떤 포인트 컷에 넣을지 -->
	  </aop:aspect>
	</aop:config>
</beans>