너와 나의 프로그래밍

Spring Framework - AOP Element와 Advice 본문

Back-End/Spring Framework

Spring Framework - AOP Element와 Advice

Whatever App's 2020. 8. 5. 08:11

 

 

 

[Spring Framework] AOP Element와 Advice

 

 

Chpater1. AOP(Aspect Oriented Programming) Element

 

가장 먼저 AOP를 사용하기 위해서는 pom.xml의 dependency 설정을 통해 라이브러리를 추가한다.

그 후 Spring 설정을 위한 .xml 파일의 namespace에 aop를 추가한다. 그 후 Bean에 AOP 기능을 사용할 Bean을 등록해주면 준비는 끝이다.

 

(pom.xml)

 

<dependency>     <groupId>org.aspectj</groupId>     <artifactId>aspectjrt</artifactId>     <version>1.9.6</version> </dependency> <dependency>     <groupId>org.aspectj</groupId>     <artifactId>aspectjweaver</artifactId>     <version>1.9.6</version> </dependency> 

(Spring 설정 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:p="<http://www.springframework.org/schema/p>" 	xmlns:context="<http://www.springframework.org/schema/context>" 	xmlns:aop="<http://www.springframework.org/schema/aop>" 	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-3.1.xsd>">  	// AOP기능을 이용할 class를 Bean에 등록. 	<context:component-scan base-package="클래스를 사용 할 package명"></context:component-scan> 	<bean id="log" class="AOP 기능을 이용할 클래스"></bean>  </beans> 

1. <aop:config>

AOP 설정에서 가장 루트가 되는 엘리먼트다. aop:config는 여러번 사용할 수 있으며 하위에는 포인트컷과 aspect 엘리먼트가 위치할 수 있다.

 

2. <aop:pointcut>

포인트컷을 지정하기 위해 사용하는 엘리먼트이며 aop:config 엘리먼트의 자식 엘리먼트로 사용할 수 있다. 물론 여러개 정의를 할 수 있으며 유일한 ID를 할당하여 애스팩트를 설정할 때 포인트컷을 참조하는 용도로 사용된다.

 

3. <aop:aspect>

핵심 관심(비지니스 로직)에 해당하는 포인트컷 메소드와 횡단 관심(AOP)에 해당하는 어드바이스 메소드를 결합하기 위해 사용된다.

 

4.<aop:advisor>

보통 트랜젝션 설정 같은 몇몇 특수한 경우 advisor를 사용한다. 물론 포인트컷과 어드바이스를 결합하는 것은 aspect와 같은 기능을 하지만 aspect의 경우엔 ID+Method를 꼭 알아야 접근이 가능하다. 하지만 어드바이스의 객체 아이디를 모르거나 아이디가 확인이 안되면 애스팩트를 설정할 수 없다.

 

(AOP Element를 사용한 예)

 

(~생략~) 	// AOP기능을 이용할 class를 Bean에 등록. 	<context:component-scan base-package="클래스를 사용 할 package명"></context:component-scan> 	<bean id="log" class="AOP 기능을 이용할 클래스"></bean> 	 	// 1. Root Element가 될 aop:config 	<aop:config> 		//2. pointcut 지정 		<aop:pointcut expression="execution(포인트컷 표현식)" id="allPointcut"/> 		 		//3. aspect Element 설정 		<aop:aspect ref="log"> 			// 4. Advice Element 설정 			<aop:before method="beforeLog" pointcut-ref="allPointcut"/> 		</aop:aspect> 	</aop:config> 

포인트 컷 표현식

 

PointCut을 지정할 때 사용하는 expression은 특별한 포인트컷 표현식을 통해 작성한다.

이 포인트컷 표현식은 어드바이스 메소드가 적용될 비지니스 메소드를 정확하게 필터링할 수 있다.

표현식은 execution() 명시자 안에 작성을 한다.

  1. 리턴 타입 지정 : 기본적인 '*' 캐릭터를 이용한다.
    • '*' : 모든 리턴타입 허용
    • void : 리턴타입이 void인 메소드
    • !void : 리턴타입이 void가 아닌 메소드
  2. 패키지 지정 : 패키지 경로를 지정할 때는 '*', '..' 캐릭터를 사용한다.
    • com.example : 정확하게 com.example 패키지만 선택
    • com.example.test... : com.example.test 패키지로 시작하는 모든 패키지 선택
    • com.example..impl : com.example 패키지로 시작되면서 마지막 패키지 이름이 impl로 끝나는 패키지 선택
  3. 클래스 지정 : 클래스 이름을 지정할 때는 '*', '+' 캐릭터를 선택한다.
    • TestServiceImpl : 정확하게 TestServiceImpl 클래스만 선택
    • *Impl : 클래스 이름이 Impl로 끝나는 클래스만 선택
    • TestService+ : 클래스 이름 뒤에 '+'가 붙으면 해당 클래스로부터 파생된 모든 자식 클래스 선택
  4. 메소드 지정 : 메소드를 지정할 때는 주로 '*' 캐릭터를 사용하고 매개변수는 '..'를 사용한다.
    • *(..) : 가장 기본 설정으로 모든 메소드 선택
    • get*(..) : 메소드 이름이 get으로 시작하는 모든 메소드 선택
  5. 매개변수 지정 : 매개변수는 '..', '*' 캐릭터를 사용하거나 정확한 타입을 지정한다.
    • (..) : 가장 기본 설정으로 '..'은 매개변수의 개수와 타입에 제약이 없다.
    • (*) : 반드시 1개의 매개변수를 가지는 메소드만 선택
    • (com.example.TestVO) : 매개변수로 TestVO를 가지는 메소드만 선택. 이때 패키지 명이 정확하게 표현되어야 한다.
    • (!com.example.TestVO) : 매개변수로 TestVO를 가지지 않는 메소드만 선택
    • (Integer, ..) : 한 개 이상의 매개변수를 가지되, 첫 번째 매개변수의 타입이 Integer인 메소드만 선택
    • (Integer, *) : 반드시 두 개의 매개변수를 가지되, 첫 번째 매개변수의 타입이 Integer인 메소드만 선택

chapter2. AOP Advice의 구현 방법

 

  1. <aop:before>
    (~생략~) 	// AOP기능을 이용할 class를 Bean에 등록. 	<context:component-scan base-package="클래스를 사용 할 package명"></context:component-scan> 	<bean id="log" class="AOP 기능을 이용할 클래스"></bean> 	 	// 1. Root Element가 될 aop:config 	<aop:config> 		//2. pointcut 지정 		<aop:pointcut expression="execution(포인트컷 표현식)" id="allPointcut"/> 		 		//3. aspect Element 설정 		<aop:aspect ref="log"> 			// 4. Advice Element 설정 			<aop:before method="beforeLog" pointcut-ref="allPointcut"/> 		</aop:aspect> 	</aop:config> 
  2. Before Advice는 포인트컷으로 지정된 메소드 호출 시, 메소드가 실행되기 전에 처리될 내용들을 기술하기 위해 사용된다.
  3. <aop:after-returning>
    (~생략~) 	// AOP기능을 이용할 class를 Bean에 등록. 	<context:component-scan base-package="클래스를 사용 할 package명"></context:component-scan> 	<bean id="log" class="AOP 기능을 이용할 클래스"></bean> 	 	// 1. Root Element가 될 aop:config 	<aop:config> 		//2. pointcut 지정 		<aop:pointcut expression="execution(포인트컷 표현식)" id="allPointcut"/> 		 		//3. aspect Element 설정 		<aop:aspect ref="log"> 			// 4. Advice Element 설정 			<aop:after-returning method="returnLog" pointcut-ref="allPointcut"/> 		</aop:aspect> 	</aop:config> 
  4. After-Returning Advice는 포인트컷으로 지정된 메소드가 정상적으로 실행되고 나서 메소드 수행 결과로 얻은 결과 데이터를 이용하여 사후 처리 로직을 추가할 때 사용한다.
  5. <aop:after-throwing>
    (~생략~) 	// AOP기능을 이용할 class를 Bean에 등록. 	<context:component-scan base-package="클래스를 사용 할 package명"></context:component-scan> 	<bean id="log" class="AOP 기능을 이용할 클래스"></bean> 	 	// 1. Root Element가 될 aop:config 	<aop:config> 		//2. pointcut 지정 		<aop:pointcut expression="execution(포인트컷 표현식)" id="allPointcut"/> 		 		//3. aspect Element 설정 		<aop:aspect ref="log"> 			// 4. Advice Element 설정 			<aop:after-returning method="throwLog" pointcut-ref="allPointcut"/> 		</aop:aspect> 	</aop:config> 
  6. After-Throwing Advice는 포인트컷으로 지정한 메소드가 실행되다가 예외가 발생하는 시점에 동작한다. 예외처리를 할 때 사용된다.
  7. <aop:after>
    (~생략~) 	// AOP기능을 이용할 class를 Bean에 등록. 	<context:component-scan base-package="클래스를 사용 할 package명"></context:component-scan> 	<bean id="log" class="AOP 기능을 이용할 클래스"></bean> 	 	// 1. Root Element가 될 aop:config 	<aop:config> 		//2. pointcut 지정 		<aop:pointcut expression="execution(포인트컷 표현식)" id="allPointcut"/> 		 		//3. aspect Element 설정 		<aop:aspect ref="log"> 			// 4. Advice Element 설정 			<aop:after method="afterLog" pointcut-ref="allPointcut"/> 		</aop:aspect> 	</aop:config>  
  8. After Advice는 예외 발생 여부에 상관없이 무조건 수행되는 어드바이스다. 보통 try-catch-finally문의 finally 문으로 생각하면 이해가 쉽다.
  9. <aop:around> Around Advice는 비지니스 메소드의 실행 전과 실행 후의 동작하여 로직을 처리하는 어드바이스다. 이때 메소드의 호출을 가로채기 위해 ProceddingJoinPoint 객체를 매개변수로 담아 가로채 사용한다.(이 부분은 다음장에서 설명...)
  10. (~생략~) // AOP기능을 이용할 class를 Bean에 등록. <context:component-scan base-package="클래스를 사용 할 package명"></context:component-scan> <bean id="log" class="AOP 기능을 이용할 클래스"></bean> // 1. Root Element가 될 aop:config <aop:config> //2. pointcut 지정 <aop:pointcut expression="execution(포인트컷 표현식)" id="allPointcut"/> //3. aspect Element 설정 <aop:aspect ref="log"> // 4. Advice Element 설정 <aop:around method="aroundLog" pointcut-ref="allPointcut"/> </aop:aspect> </aop:config>

 

 

 

참조 : 스프링 퀵 스타트

반응형