IT탐험

관점 지향 프로그래밍 본문

게시판만들기기록/스프링 프레임워크

관점 지향 프로그래밍

watercase 2021. 10. 6. 14:14
  • 웹 앱에 주기능을 추가할 때마다 보안 기능, 로깅 기능, 트랜잭션, 예외처리, 이메일 통보 기능 등의 모든 웹 앱에서 공통으로 사용하는 기능도 일일히 구현해 주어야 하는데, 이렇게 1을 구현하려다 10을 구현해야하는 상황을 스프링에서는 관점 지향 프로그래밍(AOP : Aspect Oriented Programming)으로 해결할 수 있다
  • AOP : 메서드 안의 주기능과 보조 기능을 분리한 후 선택적으로 메서드에 적용해서 사용
    • 전체 코드에 흩어져 있는 보조 기능을 하나의 장소에 모아서 관리
    • 보조 기능을 자신이 원하는 주기능에 선택적으로 적용할 수 있어 코드가 단순해지고 가독성도 향상됨
  • AOP와 관련된 용어
    • 용어 설명
      aspect 구현하고자 하는 보조 기능을 의미
      advice aspect의 실제 구현체(클래스)를 의미, 메서드 호출을 기준으로 여러 지점에서 실행
      joinpoint advice를 적용하는 지점을 의미, 스프링은 method 결합점만 제공
      pointcut advice가 적용되는 대상을 지정, 패키지이름/클래스이름/메서드이름을 정규식으로 지정하여 사용
      target advice가 적용되는 클래스를 의미
      weaving advice를 주기능에 적용하는 것을 의미
  • AOP 기능을 구현하는 방법
    • 스프링 프레임워크에서 제공하는 AOP관련 API를 이용
    • @Aspect 애너테이션을 이용
  • 스프링 API를 이용한 AOP 기능 구현 과정
    1. Target 클래스를 지정
    2. Advice 클래스를 지정
    3. 설정 파일에서 Pointcut을 설정
    4. 설정 파일에서 어드바이스와 포인트컷을 결합하는 어드바이저 설정
    5. 설정 파일에서 스프링의 ProxyFactoryBean 클래스를 이용해 타깃에 어드바이스를 설정
    6. getBean() 메서드로 빈 객체에 접근해 사용
  • 스프링에서 제공하는 메서드를 호출했을 때 AOP 기능을 수행하는 어드바이스 인터페이스들의 추상메서드 기능
    • 인터페이스 추상메서드 설명
      MethodBeforeAdvice void before(Method method, Object[] args, Object target) throws Throwable 해당 메서드가 실행되기 전 실행
      Method method : 대상 객체에서 실행된 메서드를 나타내는 메서드 객체
      Object[] args : 메서드 인자 목록
      Object target : 대상 객체
      AfterReturningAdvice void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable 해당 메서드가 실행된 후 실행
      Object returnValue : 대상 객체의 메서드가 반환하는 값
      ThrowsAdvice void afterThrowing(Method method, Object[] args, Object target, Exception ex) 해당 메서드에서 예외 발생 시 실행
      Exception ex : 발생한 예외 타입
      MethodInterceptor Object invoke(MethodInvocation invocation) throws Throwable 해당 메서드의 실행 전/후와 예외 발생 시 실행
      MethodInvocation invocation : 대상 객체의 모든 정보를 담고 있는 객체(호출된 메서드, 인자 등)
    • 인터페이스 MethodInterceptor 는 invoke() 메서드를 이용해 다른 세 가지 인터페이스의 기능을 동시에 수행할 수 있다
  • AOP를 XML로 설정 예시 
    • 더보기
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
         "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
      <beans>
         <bean id="calcTarget" class="com.spring.ex01.Calculator" />
         <bean id="logAdvice" class="com.spring.ex01.LoggingAdvice" />
         
         <bean id="proxyCal"
                class="org.springframework.aop.framework.ProxyFactoryBean">
            <property name="target" ref="calcTarget"/>
            <property name="interceptorNames">
               <list>
                  <value>logAdvice</value>
               </list>
            </property>
         </bean>
      </beans>
  • 어드바이스 클래스 구현 예시
    • 더보기
      package com.spring.ex01;
      
      import org.aopalliance.intercept.MethodInterceptor;
      import org.aopalliance.intercept.MethodInvocation;
      
      public class LoggingAdvice implements MethodInterceptor {
      	public Object invoke(MethodInvocation invocation) throws Throwable {
      		System.out.println("[메서드 호출 전 : LogginAdvice");
      		System.out.println(invocation.getMethod() + "메서드 호출 전");
      
      		Object object = invocation.proceed();
      
      		System.out.println("[메서드 호출 후 : loggingAdvice");
      		System.out.println(invocation.getMethod() + "메서드 호출 후");
      		return object;
      	}
      }
  • AOP를 적용한 클래스 사용 예시
    • 더보기
      package com.spring.ex01;
      
      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");
      
      	      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);
      	   }
      	}
    • 실제 스프링에서는 특정 패키지 이름이나 특정 클래스 이름에만 AOP 기능을 적용할 수도 있다

 

'게시판만들기기록 > 스프링 프레임워크' 카테고리의 다른 글

스프링 JDBC  (0) 2021.10.07
스프링 MVC  (0) 2021.10.06
의존성 주입과 제어의 역전  (0) 2021.10.06
프레임워크란  (0) 2021.10.05
모델2  (0) 2021.10.05
Comments