Servlet JSP MVC Spring

[Spring] 관점 지향 프로그래밍_ AOP

vhxpffltm 2020. 4. 12. 15:49
반응형

AOP

 

메서드 안의 주기능과 보조 기능을 분리한 후 선택적으로 메서드에 적용해서 사용하는 개념이다.

 

전체 코드에 흩어져 있는 보조 기능을 하나의 장소에 모아 관리할 수 있다. 또한 보조 기능을 자신이 원하는 주기능에 선택적으로 적용할 수 있으므로 코드가 단순해지고 가독성이 향상된다.

 

예를 들면 아래와 같다. 각각의 보조 기능을 미리 만들어 놓고 설정만 하여 각각의 주기능을 수행하는 메서드나 클래스에 선택적으로 보조 기능이 적용된다.

 

 

이제 간단하게 스프링 API를 이용하여 AOP를 구현해보자.

 

그 과정은 좀 복잡하다.

타깃(target) 클래스를 지정하고, Advice 클래스를 지정하고, 설정 파일에서 pointcut을 지정한다.

설정 파일에서 Advice와 Pointcut을 결합하는 Adviser를 설정하고, 스프링의 ProxyFactoryBean 클래스를 이용해 target에 advice를 설정한다.

마지막으로 getBean 메서드로 빈 객체에 접근해 사용한다.

 

간단하게 코드를 작성해보자.

 

 

AOPTest.xml 은 <bean> 태그를 이용해 타깃 bean과 어드바이스 bean을 생성한 후 proxyFactorybean 클래스 bean 생성 시 <property> 태그로 타깃 bean과 어드바이스 bean을 엮는다. 그리고 사용할 어드바이스가 여러개이면 <value>태그로 추가한다. 

어드바이스 클래스인 LoggingAdvice는 인터페이스를 구현하고 invocation.proceed() 메서를 기준으로 호출 전과 호출 후로 메세지를 구분한다. 

proceed 메서드 호출 전은 타깃 메서드에서 호출 전 실행하는 것이고 호출 후 구문은 타깃 메서드 호출 후 실행하는 기능이다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
<beans>
   <bean id="calcTarget" class="com.spring.ex03.Calculator" />
   <bean id="logAdvice" class="com.spring.ex03.LoggingAdvice" />
   <!-- 타깃 클래스 bean과 로그 기능을 하는 어드바이스 bean을 지정한다.. -->
   <bean id="proxyCal"
       <!-- 스프링 프레임워크에서 제공하는 proxyfactorybean을 사용해 타깃과 어드바이스를 엮어줌 -->
      <property name="target" ref="calcTarget"/> <!-- 타깃 bean을 calcTarget bean으로 지정 -->
      <property name="interceptorNames">
         <list>
            <value>logAdvice</value>
         </list>
      </property> 
      <!-- proxyfactorybean의 interceptornames 속성에 logAdvice bean으로 설정하여 타깃 클래스의 메서드 호출 시 해당 value를 실행 -->
   </bean>
</beans>
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

 

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
 
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
 
public class LoggingAdvice implements MethodInterceptor{// 인터페이스 MethodInterceptor를 구현하여 어드바이스 클래스 만듬
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("[메서드 호출 전 : LogginAdvice");
        System.out.println(invocation.getMethod() + "메서드 호출 전");
        // 메서드 호출 전에 수행을 위한 출력
        Object object = invocation.proceed(); // invocation을 이용해 메서드 호출
 
        System.out.println("[메서드 호출 후 : loggingAdvice");
        System.out.println(invocation.getMethod() + "메서드 호출 후");
        //호출 후의 출력
        return object;
    }
}
////////////////////////////////////////////////////////////////////////////////////////////
 
public class Calculator {
    public void add(int x, int y) {
        int result=x+y;
        System.out.println("더하기 결과 :"+ result);
    }
    public void subtract(int x, int y) {
        int result=- y;
        System.out.println("빼기 결과 : "+ result);
    }
    public void multiply(int x, int y) {
        int result=* y;
        System.out.println("곱하기 결과 : "+ result);
    }
    public void divide(int x, int y) {
        int result=/ y;
        System.out.println("나누기 결과 : "+ result);
    }
}
///////////////////////////////////////////////////////////////////////////////////////////
 
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class CalcTest {
     public static void main(String[] args){
          ApplicationContext context=new ClassPathXmlApplicationContext("AOPTest.xml");
          Calculator cal=(Calculator)context.getBean("proxyCal");
          //id가 proxyCal 인 bean에 접근
          cal.add(100,20);
          System.out.println();
          cal.subtract(100,20);
          System.out.println();
          cal.multiply(100,20);
          System.out.println();
          cal.divide(100,20); // 메서드 호출 전후에 어드바이스 bean이 적용
       }
}
 
 
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

 

결과 출력 전후에서 각 메서드 정보를 출력한다.

이 AOP 기능을 실제 스프링에서는 특정 패키지 이름이나 클래스 이름, 메서드 이름으로만 AOP기능을 적용한다.

 

스프링 MVC 기능, JDBC, 마이바티스 프레임워크 연동, 트랜잭션, 애너테이션 등의 다양한 기능이 있지만, 관련 기능을 자세히 알아보기보단 메이븐과 STS를 사용하여 스프링 프로젝트를 직접 개발해본다. 

 

 

 

Reference

자바 웹을 다루는 기술

반응형