너와 나의 프로그래밍
Spring Framework - AOP Element와 Advice 본문
[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() 명시자 안에 작성을 한다.
- 리턴 타입 지정 : 기본적인 '*' 캐릭터를 이용한다.
- '*' : 모든 리턴타입 허용
- void : 리턴타입이 void인 메소드
- !void : 리턴타입이 void가 아닌 메소드
- 패키지 지정 : 패키지 경로를 지정할 때는 '*', '..' 캐릭터를 사용한다.
- com.example : 정확하게 com.example 패키지만 선택
- com.example.test... : com.example.test 패키지로 시작하는 모든 패키지 선택
- com.example..impl : com.example 패키지로 시작되면서 마지막 패키지 이름이 impl로 끝나는 패키지 선택
- 클래스 지정 : 클래스 이름을 지정할 때는 '*', '+' 캐릭터를 선택한다.
- TestServiceImpl : 정확하게 TestServiceImpl 클래스만 선택
- *Impl : 클래스 이름이 Impl로 끝나는 클래스만 선택
- TestService+ : 클래스 이름 뒤에 '+'가 붙으면 해당 클래스로부터 파생된 모든 자식 클래스 선택
- 메소드 지정 : 메소드를 지정할 때는 주로 '*' 캐릭터를 사용하고 매개변수는 '..'를 사용한다.
- *(..) : 가장 기본 설정으로 모든 메소드 선택
- get*(..) : 메소드 이름이 get으로 시작하는 모든 메소드 선택
- 매개변수 지정 : 매개변수는 '..', '*' 캐릭터를 사용하거나 정확한 타입을 지정한다.
- (..) : 가장 기본 설정으로 '..'은 매개변수의 개수와 타입에 제약이 없다.
- (*) : 반드시 1개의 매개변수를 가지는 메소드만 선택
- (com.example.TestVO) : 매개변수로 TestVO를 가지는 메소드만 선택. 이때 패키지 명이 정확하게 표현되어야 한다.
- (!com.example.TestVO) : 매개변수로 TestVO를 가지지 않는 메소드만 선택
- (Integer, ..) : 한 개 이상의 매개변수를 가지되, 첫 번째 매개변수의 타입이 Integer인 메소드만 선택
- (Integer, *) : 반드시 두 개의 매개변수를 가지되, 첫 번째 매개변수의 타입이 Integer인 메소드만 선택
chapter2. AOP Advice의 구현 방법
- <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>
- Before Advice는 포인트컷으로 지정된 메소드 호출 시, 메소드가 실행되기 전에 처리될 내용들을 기술하기 위해 사용된다.
- <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>
- After-Returning Advice는 포인트컷으로 지정된 메소드가 정상적으로 실행되고 나서 메소드 수행 결과로 얻은 결과 데이터를 이용하여 사후 처리 로직을 추가할 때 사용한다.
- <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>
- After-Throwing Advice는 포인트컷으로 지정한 메소드가 실행되다가 예외가 발생하는 시점에 동작한다. 예외처리를 할 때 사용된다.
- <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>
- After Advice는 예외 발생 여부에 상관없이 무조건 수행되는 어드바이스다. 보통 try-catch-finally문의 finally 문으로 생각하면 이해가 쉽다.
- <aop:around> Around Advice는 비지니스 메소드의 실행 전과 실행 후의 동작하여 로직을 처리하는 어드바이스다. 이때 메소드의 호출을 가로채기 위해 ProceddingJoinPoint 객체를 매개변수로 담아 가로채 사용한다.(이 부분은 다음장에서 설명...)
(~생략~) // 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>
참조 : 스프링 퀵 스타트
'Back-End > Spring Framework' 카테고리의 다른 글
Spring Framework - AOP JoinPoint와 Annotation (4) | 2020.08.10 |
---|---|
Spring Framework - Spring AOP의 개념과 용어 (0) | 2020.07.27 |
Spring Framework - Annotation 기반 설정 - 2 (0) | 2020.07.12 |
Spring Framework - Annotation 기반 설정 - 1 (2) | 2020.07.11 |
Spring Framework - 의존성 주입 방식 (0) | 2020.07.08 |