개키우는개발자 : )

AOP애플리케이션 작성(1) 본문

JAVA/Spring Framework

AOP애플리케이션 작성(1)

DOGvelopers 2019. 2. 8. 14:52
반응형

Spring Framework AOP애플리케이션 작성(1)



학습 목표


  • Advice 클래스 작성
  • AOP 설정 및 테스트
  • PointCut 표현식에 대한 이해


프로젝트 목록프로젝트 목록



1.Advice 클래스 작성


1-1 Spring AOP의 구현방식


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

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

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

(즉, 어드바이스와 포인트컷을 설정함)


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

- @Aspect 어노테이션을 이용해서 부가기능을 제공하는 Aspect 클래스를 작성한다. 이때 Aspect 클래스는 어드바이스를 구현하는 메서드와 포인트컷을 포함한다.


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


1-2 Advice의 종류


- Around 어드바이스 : 타겟의 메서드가 호출되기 이전(before) 시점과 이후(after) 시점에 모두 처리해야 할 필요가 있는 부가기능을 정의한다 -> Joinpoint 앞과 뒤에 실행되는 Advice


- Before 어드바이스 : 타겟의 메서드가 실행되기 이전(before) 시점에 처리해야 할 필요가 있는 부가기능을 정의한다. -> Joinpoint 앞에서 실행되는 Advice


- After Returning 어드바이스 : 타겟의 메서드가 정상적으로 실행된 이후(after) 시점에 처리해야 할 필요가 있는 부가기능을 정의한다. -> Joinpoint 메서드 호출이 정상적으로 종료된 뒤에 실행되는 Advice


- After Throwing 어드바이스 : 타겟의 메서드가 예외를 발생된 이후(after) 시점에 처리해야 할 필요가 있는 부가기능을 정의한다. -> 예외가 던져질 때 실행되는 Advice


1-3 Advice 클래스 정보


- 클래스명 : PerformanceTraceAdvice.java


- 클래스 기능 : 이 어드바이스는 타겟 객체의 메서드 실행 시간을 계산해서 출력해주는 부가기능을 제공한다.


- Advice 유형 : Around 어드바이스(타겟 객체의 메서드 실행 전, 후의 시간을 측정하여 계산하면 타겟 객체의 메서드 실행 시간을 알 수 있음)


- 구현 메서드명 : trace(ProceedingJoinPoint joinPoint)


1-4 JoinPoint 인터페이스


- JoinPoint는 Spring AOP 혹은 AspectJ에서 AOP가 적용되는 지점을 뜻한다.


- 해당 지점을 AspectJ에서 JoinPoint라는 인터페이스로 나타낸다.


- JoinPoint 인터페이스는 getArgs() ( 메서드 아규먼트를 반환한다), getThis() (프록시 객체를 반환한다), getTarget() (대상 객체를 반환한다), getSignature() (어드바이즈 되는 메서드 설명(description)을 반환한다),

toString() (어드바이즈 되는 메서드의 설명을 출력한다) 과 같은 다수의 유용한 메서드를 제공한다.


- 모든 어드바이스는 org.aspectj.lang.JoinPoint 타입의 파라미터를 어드바이스 메서드에 첫 번째 매개변수로 선언할 수 있다.


- Around 어드바이스는 JoinPoint의 하위 클래스인 ProceedingJoinPoint 타입의 파라미터를 필수적으로 선언 해야한다.


https://www.eclipse.org/aspectj/doc/next/runtime-api/index.html


1-5 PerfomanceTraceAdvice.java 작성


New -> package -> myspring.aop.xml 패키지 생성


myspring.aop.xml 하위 -> New -> class -> PerfomanceTraceAdvice 클래스 생성


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package myspring.aop.xml;
 
import org.aspectj.lang.ProceedingJoinPoint;
 
public class PreformanceTraceAdvice {
 
    public Object trace(ProceedingJoinPoint joinPoint) throws Throwable{
        Object result;
        //타겟 메서드의 signature 정보
        String signatureString = joinPoint.getSignature().toShortString();
        System.out.println(signatureString + "시작");
        
        //타겟의 메서드가 호출되기 전의 시간
        long start =System.currentTimeMillis();
        try {
            //타겟의 메서드 호출
            result = joinPoint.proceed();
            return result;
        } finally {
            // 타겟의 메서드가 호출된 후의 시간
            long finish = System.currentTimeMillis();
            System.out.println(signatureString + "종료");
            System.out.println(signatureString + "실행 시간 : " + (finish - start) + " ms");
        }
    }
    
}
 
cs



2.AOP 설정 및 테스트



2-1 Advice 클래스를 Bean으로 등록


- 작성한 Advice 클래스를 XML 설정파일에 Bean으로 등록해야 한다.


Config폴더 하위 -> New -> Spring -> Spring Bean Configuration File -> aop.xml 생성


Config폴더 하위 -> New -> SpringConfig폴더 하위 -> New -> Spring 검색


aop.xml 생성aop.xml 생성


aop,beans 체크aop,beans 체크


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
    
    <!-- Advice 클래스를 Bean으로 등록 -->
    <bean id="performancdTraceAdvice" class="myspring.aop.xml.PreformanceTraceAdvice" />
    
    <!-- AOP 설정 -->
    <aop:config>
        <aop:aspect id="traceAspect" ref="performancdTraceAdvice">
            <aop:around pointcut="execution(public * myspring.user.service..*(..))" method="trace" />
        </aop:aspect>
    </aop:config>
    
</beans>
cs



2-2 AOP 설정


- <aop:config> : AOP 설정 정보임을 나타낸다.


- <aop:aspect> : 애스펙트를 설정한다.


- <aop:around pointcut="execution()"> : Around 어드바이스와 포인트컷을 설정한다.



2-3 AOP 설정에 대한 설명


- <aop:aspect> 태그의 ref 속성은 애스펙트로서 기능을 제공할 Bean을 설정할 때 사용함.


- <aop:around> 태그의 pointcut 속성의 execution 지시자(designator)는 어드바이스를 적용할 패키지, 클래스, 메서드를 표현할 때 사용됨.


- myspring.user.service 패키지 및 그 하위 패키지에 있는 모든 public 메서드를 포인트컷으로 설정하고 있음


- UserServiceImpl의 public 메서드가 호출될 때 PerformanceTraceAdvice Bean의 trace() 메서드가 호출 되도록 설정 하고 있음.


2-4 Around Advice와 AOP 설정 테스트


- UserService Bean의 메서드를 호출하면, Around Advice가 적용된 것을 확인해 볼 수 있다.


1
2
3
4
5
6
@Test
public void getUserTest() {
    UserVO user = service.getUser("user1");
    System.out.println(user);
    assertEquals("name1",user.getName());
}
cs


1
2
3
UserService.getUser(..)시작
UserService.getUser(..)종료
UserService.getUser(..)실행 시간 : 243 ms
cs


2-5 Advice를 정의하는 태그


- 각 타입의 Advice를 정의하기 위해 아래와 같은 태그를 제공한다.


- <aop:before> : 메서드 실행 전에 적용되는 어드바이스를 정의한다.

- <aop:after-returning> : 메서드가 정상적으로 실행된 후에 적용되는 어드바이스를 정의한다.

- <aop:after-throwing> : 메서드가 예외를 발생시킬 때 적용되는 어드바이스를 정의한다. try-catch 블록에서 catch 블록과 비슷하다.

- <aop:after> : 메서드 정상적으로 실행되는지 또는 에외를 발생시키는지 여부에 상관엇ㅂ이 어드바이스를 정의한다. try-catch-finally에서 finally 블록과 비슷하다

- <aop:around> : 메서드 호출 이전, 이후, 예외 발생 등 모든 시점에 적용 가능한 어드바이스를 정의한다.



3.PointCut 표현식


3-1 PointCut 표현식 문법


- AspectJ 포인트컷 표현식은 포인트컷 지시자를 이용하여 작성한다.


- 포인트컷 지시자 중에서 가장 대표적으로 사용되는 것은 execution()이다.


- execution() 지시자를 사용한 포인트컷 표현식의 문법구조는 다음과 같다.


PointCut 표현식 문법PointCut 표현식 문법



3-2 PointCut 표현식 예시


PointCut 표현식 예시PointCut 표현식 예시


execution(* hello(..))

- hello라는 이름을 가진 메서드를 선정하는 것이다. 파라미터는 모든 종류를 다 허용한다.


execution(* hello())

- 파라미터 패턴이 ()로 되어 있으니 hello 메서드 중에서 파라미터가 없는 것만 선택한다.


execution(* myspring.user.service.UserServiceImpl.*(..))

myspring.user.service.UserServiceImpl 클래스를 직접 지정하여 이 클래스가 가진 모든 메서드를 선택한다.


execution(* myspring.user.service.*.*(..))

myspring.user.service 패키지의 모든 클래스에 적용된다. 하지만 서브패키지의 클래스는 포함되지 않는다.


execution(* myspring.user.service..*.*(..))

myspring.user.service 패키지의 모든 클래스에 적용된다. 그리고 '..' 를 사용해서 서브패키지의 모든 클래스까지 포함한다.


execution(* *..Target.*(..))

- 패키지에 상관없이 Target 이라는 이름의 모든 클래스에 적용된다. 다른 패키지에 같은 이름의 클래스가 있어도 적용이 된다는 점에 유의해야 함.



완성된 프로젝트 코드를 다운받으실수 있습니다.

https://dog-developers.tistory.com/30

반응형

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

MyBatis(마이바티스) 개요  (2) 2019.02.08
AOP애플리케이션 작성(2)  (0) 2019.02.08
AOP 개요  (0) 2019.02.08
Spring Framework JDBC 환경설정  (0) 2019.02.07
Spring Framework JDBC 개요  (0) 2019.02.07
Comments