ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring] 004. AOP 의 관찰 (2) : AOP Advice
    SsY 2023. 6. 29. 10:17
    728x90
    SpringPrj08
    - Before Advice
    - 어떤 방법으로 간단하게 처리하는지 확인
    ■■■ AOP 개념 실습 04 (Spring AOP 기법) ■■■
    ※ AOP Advice
       Advice - 언제 어떤 공통 관심사항(보조 업무, cross-cutting concern)을
                적용할지 결정하는 방법
       Before Advice - 보조 업무가 주 업무 실행 전에 수행되는 경우 
       After Advice  - 보조 업무가 주 업무 실행 후에 수행되는 경우
       Around Advice - 보조 업무가 주 업무 실행 전과 후에 수행되는 경우
    
    ○ 실습 성격 및 주요 사항
    1. 콘솔프로젝트 → Java Project → SpringPrj08
    2. 기본적인 산술 연산처리  
    3. AOP 기법을 사용하지 않은 상태로 보조 업무를 적용시켜보는 실습 진행
       ※ 보조 업무 → 시간 측정 및 로그 기록
    4. 로그 및 스톱워치 기능을 사용하기 위해 관련 jar 파일을 등록하여 실습을 진행할 수 있도록 한다.
    
    ○ 등록해야 할 jar 파일
       (로그 기록 및 스톱워치 사용을 위해 등록한 jar 파일)
       + 스프링 AOP 기법을 적용하기 위한 jar 파일
    - 경로1 : C:\s-f-3.0.2-with-docs\dist
      ·파일1 :  org.springframework.asm-3.0.2.RELEASE.jar           (asm)
      ·파일2 :  org.springframework.beans-3.0.2.RELEASE.jar         (beans)
      ·파일3 :  org.springframework.context-3.0.2.RELEASE.jar       (context)
      ·파일4 :  org.springframework.core-3.0.2.RELEASE.jar          (core)
      ·파일5 :  org.springframework.expression-3.0.2.RELEASE.jar    (expression)
      ·파일6 :  org.springframework.aop-3.0.2.RELEASE.jar           (aop)
                 (→ IoC/DI 실습 항목과 비교하여 추가되는 항목)
    - 경로2 : C:\s-f-3.0.2-dependencies\org.apache.commons\com.springsource.org.apache.commons.logging\1.1.1
      ·파일7 :  com.springsource.org.apache.commons.logging-1.1.1.jar
    - 경로3 : C:\s-f-3.0.2-dependencies\org.aopalliance\com.springsource.org.aopalliance\1.0.0
      ·파일8 :  com.springsource.org.aopalliance-1.0.0.jar
                 (→ IoC/DI 실습 항목과 비교하여 추가되는 항목)
      
    ○ 물리적 파일 구성
    1. Calculator.java             → 인터페이스 (기존 소스코드 그대로 활용)
    2. CalculatorAspect.java       → 보조 업무 클래스 
                                      보조 업무 적용 및 주 업무 호출 과정
    3. CalculatorImpl.java         → 클래스. 주 업무만 적용 (기존 소스코드 그대로 활용)
    4. Main.java                   → 클래스. main() 메소드를 포함하는 테스트 클래스
    5. config.xml                  → 스프링 환경 설정 파일
                                      객체 생성 및 DI 설정
                                      (applicationContext.xml 과 동일하나 이름만 바꿔 사용해봄)
    6. CalculatorBeforeAdvice.java → 추가. Before Advice

    기존 SpringPrj07 코드 그대로 사용

    • Calculator.java
    • CalculatorAspect.java
    • CalculatorImpl.java
    • Main.java

    • config.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"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    
    	<!--
    		※ 스프링이 제공하는 환경 설정 XML 파일 샘플
    		   → 스프링이 생성하고 관리해야 할 객체들에 대한 정보 전달
    	-->
    	
    	<!-- CalculatorImpl 클래스의 객체 생성 및 관리를 위한 정보 전달 -->
    	<bean id="cal" class="com.test.spr.CalculatorImpl"></bean>
    	
    	<!-- CalculatorAspect 클래스의 객체 생성 및 관리를 위한 정보 전달 -->
    	<bean id="aspect" class="com.test.spr.CalculatorAspect"></bean>
    	
    	<!-- CHECK!!!!! -->
    	<!-- 추가 -->	
    	<!-- CalculatorBeforeAdvice 클래스의 객체 생성 및 관리를 위한 정보 전달 -->
    	<bean id="before" class="com.test.spr.CalculatorBeforeAdvice"></bean>
    	
    	<!-- 스프링이 제공하는 가짜 객체(Proxy) 클래스의 객체 생성 및 관리를 위한 정보 전달 -->
    	<!-- → 『ProxyFactoryBean』 -->
    	<!-- 다른 메소드에서 위 이름으로 인텔리전스 기능 이용하여 import 주소 가져와서 class 에 붙여넣기 -->
    	<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    	
    		<!-- 주 업무 클래스의 인터페이스 정보 제공 -->
    		<!-- 『proxyInterfaces』 -->
    		<property name="proxyInterfaces">
    			<list>
    				<value>com.test.spr.Calculator</value>
    				<!-- 여러 개의 인터페이스 적용 가능
    				<value>com.test.spr.Calculator</value>
    				<value>com.test.spr.Calculator</value>
    				-->
    			</list>
    		</property>
    		
    		<!-- 주 업무 클래스의 객체 정보 제공 -->
    		<!-- 『target』 -->
    		<!-- 위에서 만든 인스턴스의 정보를 참조하게 끔 설정해줌 -->
    		<property name="target" ref="cal"></property>
    		
    		<!-- 보조 업무 클래스의 객체 정보 제공 -->
    		<!-- 『interceptorNames』 -->
    		<property name="interceptorNames">
    			<list>
    				<!-- 여러 보조 업무 들로 적용 가능 -->
    				<!-- Around Advice -->
    				<value>aspect</value>
    
    				<!-- Before Advice : 순서는 상관이 없음. 사전적인 약속이 더 중요 -->
    				<value>before</value>
    			</list>
    		</property>
    	</bean>
    
    </beans>

    • CalculatorBeforeAdvice.java
    /*=============================
       CalculatorBeforeAdvice.java
       - Before Advice 구성
    ============================= */
    
    package com.test.spr;
    
    import java.lang.reflect.Method;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.aop.MethodBeforeAdvice;
    
    //-- 업무 구성을 함에 있어서 스프링에게 Before Advice 라고 알리는 기능
    public class CalculatorBeforeAdvice implements MethodBeforeAdvice
    {
    	// MethodBeforeAdviece 메소드 재정의
    	@Override
    	public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable
    	{
    		Log log = LogFactory.getLog(this.getClass());
    		log.info("Before Advice 실행--------------------");
    		log.info("주 업무 실행 전에 수행되어야 하는 업무");
    		log.info("--------------------Before Advice 실행");
    	}
    	
    }

    SpringPrj09
    - After Throwing Advice
    - throw 는 업무를 수행함으로써 발생하기 때문에, before Throw 는 없다
    ■■■ AOP 개념 실습 05 (Spring AOP 기법) ■■■
    ※ AOP Advice
       Advice - 언제 어떤 공통 관심사항(보조 업무, cross-cutting concern)을
                적용할지 결정하는 방법
       Before Advice - 보조 업무가 주 업무 실행 전에 수행되는 경우 
       After Advice  - 보조 업무가 주 업무 실행 후에 수행되는 경우
       Around Advice - 보조 업무가 주 업무 실행 전과 후에 수행되는 경우
    
    ○ 실습 성격 및 주요 사항
    1. 콘솔프로젝트 → Java Project → SpringPrj09
    2. 기본적인 산술 연산처리  
    3. AOP 기법을 사용하지 않은 상태로 보조 업무를 적용시켜보는 실습 진행
       ※ 보조 업무 → 시간 측정 및 로그 기록
    4. 로그 및 스톱워치 기능을 사용하기 위해 관련 jar 파일을 등록하여 실습을 진행할 수 있도록 한다.
    
    ○ 등록해야 할 jar 파일
       (로그 기록 및 스톱워치 사용을 위해 등록한 jar 파일)
       + 스프링 AOP 기법을 적용하기 위한 jar 파일
    - 경로1 : C:\s-f-3.0.2-with-docs\dist
      ·파일1 :  org.springframework.asm-3.0.2.RELEASE.jar           (asm)
      ·파일2 :  org.springframework.beans-3.0.2.RELEASE.jar         (beans)
      ·파일3 :  org.springframework.context-3.0.2.RELEASE.jar       (context)
      ·파일4 :  org.springframework.core-3.0.2.RELEASE.jar          (core)
      ·파일5 :  org.springframework.expression-3.0.2.RELEASE.jar    (expression)
      ·파일6 :  org.springframework.aop-3.0.2.RELEASE.jar           (aop)
                 (→ IoC/DI 실습 항목과 비교하여 추가되는 항목)
    - 경로2 : C:\s-f-3.0.2-dependencies\org.apache.commons\com.springsource.org.apache.commons.logging\1.1.1
      ·파일7 :  com.springsource.org.apache.commons.logging-1.1.1.jar
    - 경로3 : C:\s-f-3.0.2-dependencies\org.aopalliance\com.springsource.org.aopalliance\1.0.0
      ·파일8 :  com.springsource.org.aopalliance-1.0.0.jar
                 (→ IoC/DI 실습 항목과 비교하여 추가되는 항목)
      
    ○ 물리적 파일 구성
    1. Calculator.java             → 인터페이스 (기존 소스코드 그대로 활용)
    2. CalculatorAspect.java       → 보조 업무 클래스 
                                      보조 업무 적용 및 주 업무 호출 과정
    3. CalculatorImpl.java         → 클래스. 주 업무만 적용 (기존 소스코드 그대로 활용)
    4. Main.java                   → 클래스. main() 메소드를 포함하는 테스트 클래스
    5. config.xml                  → 스프링 환경 설정 파일
                                      객체 생성 및 DI 설정
                                      (applicationContext.xml 과 동일하나 이름만 바꿔 사용해봄)
    6. CalculatorBeforeAdvice.java → Before Advice
    7. CalculatorAfterThrowing.java → 추가. After Throwing Advice
                                       //-- 업무 수행 후에 예외 Throw 가 발생하면 실행되는 사후 보조 업무

    SpringPrj08 에서 사용한 기존 파일 활용

    • Calculator.java
    • CalculatorAspect.java
    • CalculatorBeforeAdvice

    예외사항을 발생시키기 위한 업무 설정

    • Main.java
    /*=========================================
       Main.java
       - 클래스
       - main() 메소드가 포함된 테스트 클래스
    ===========================================*/
    package com.test.spr;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    
    public class Main
    {
    
    	public static void main(String[] args)
    	{
    		// 주 업무(core concern) 실행에 대한 테스트 → Spring AOP 기법을 적용한 후~!!!
    	    ApplicationContext context = new ClassPathXmlApplicationContext("config.xml");
    	    
    	    //Calculator cal = new CalculatorImpl();
    	    //Calculator cal = (Calculator)객체수신;
    	    //Calculator cal = (Calculator)context.getBean("proxy");
    	    Calculator cal = context.getBean("proxy", Calculator.class);
    	    
            // 예외 상황이 발생할 수 있도록 값을 넘길 수 있는 코드 구성
    	    int add = cal.add(100, 200);
    	    System.out.println(add);
    
    
    	    
    	    
    	   }
    
    		
    	}// end main()

    • CalculatorImpl.java
    /*=============================================
       CalculatorImpl.java
       - 클래스
       - Calculator 인터페이스를 구현하는 클래스
       - 주 업무만 적용된 형태로 구성
    ============================================= */
    package com.test.spr;
    
    public class CalculatorImpl implements Calculator
    {
    	// 주 업무(core concern) 진행을 위한 메소드 구현
    
    	@Override
    	public int add(int x, int y)
    	{
    		int result = 0;
    		
    		// ※ 주 업무(core concern)를 수행하는 과정에서 예외 상황을 만들기 위해
    		//    예외 객체를 생성
    		//    - try ~ catch ~ finally : 예외 발생 시 자체적으로 처리
    		//    - throws                : 예외 발생 시 자신을 호출한 객체에 예외를 넘기는 처리
    		//    - throw                 : 예외를 인위적으로 발생시키는 처리
    		if (x>100 || y>100)
    		{
    			throw new IllegalArgumentException("100보다 큰 인자를 전달한 예외 발생");
    		}
    
    		result = x + y;
    		System.out.printf("%d + %d = %d%n", x, y, result);
    		
    		return result;
    	}
    
    	@Override
    	public int sub(int x, int y)
    	{
    		int result = 0;
    		
    		result = x - y;
    		System.out.printf("%d - %d = %d%n", x, y, result);
    		
    		return result;
    	}
    
    	@Override
    	public int multi(int x, int y)
    	{
    		int result = 0;
    		
    		result = x * y;
    		System.out.printf("%d * %d = %d%n", x, y, result);
    		
    		return result;
    	}
    
    	@Override
    	public int div(int x, int y)
    	{
    		int result = 0;
    		
    		result = x / y;
    		System.out.printf("%d / %d = %d%n", x, y, result);
    		
    		return result;
    	}
    	
    	
    }

    • config.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"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    
    	<!--
    		※ 스프링이 제공하는 환경 설정 XML 파일 샘플
    		   → 스프링이 생성하고 관리해야 할 객체들에 대한 정보 전달
    	-->
    	
    	<!-- CalculatorImpl 클래스의 객체 생성 및 관리를 위한 정보 전달 -->
    	<bean id="cal" class="com.test.spr.CalculatorImpl"></bean>
    	
    	<!-- CalculatorAspect 클래스의 객체 생성 및 관리를 위한 정보 전달 -->
    	<bean id="aspect" class="com.test.spr.CalculatorAspect"></bean>
    
    	<!-- CalculatorBeforeAdvice 클래스의 객체 생성 및 관리를 위한 정보 전달 -->
    	<bean id="before" class="com.test.spr.CalculatorBeforeAdvice"></bean>
    	
    	<!-- CHECK!!!!! -->
    	<!-- 추가 -->	
    	<!-- CalculatorAfterThrowing 클래스의 객체 생성 및 관리를 위한 정보 전달 -->
    	<bean id="afterThrowing" class="com.test.spr.CalculatorAfterThrowing"></bean>
    	
    	<!-- 스프링이 제공하는 가짜 객체(Proxy) 클래스의 객체 생성 및 관리를 위한 정보 전달 -->
    	<!-- → 『ProxyFactoryBean』 -->
    	<!-- 다른 메소드에서 위 이름으로 인텔리전스 기능 이용하여 import 주소 가져와서 class 에 붙여넣기 -->
    	<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    	
    		<!-- 주 업무 클래스의 인터페이스 정보 제공 -->
    		<!-- 『proxyInterfaces』 -->
    		<property name="proxyInterfaces">
    			<list>
    				<value>com.test.spr.Calculator</value>
    				<!-- 여러 개의 인터페이스 적용 가능
    				<value>com.test.spr.Calculator</value>
    				<value>com.test.spr.Calculator</value>
    				-->
    			</list>
    		</property>
    		
    		<!-- 주 업무 클래스의 객체 정보 제공 -->
    		<!-- 『target』 -->
    		<!-- 위에서 만든 인스턴스의 정보를 참조하게 끔 설정해줌 -->
    		<property name="target" ref="cal"></property>
    		
    		<!-- 보조 업무 클래스의 객체 정보 제공 -->
    		<!-- 『interceptorNames』 -->
    		<property name="interceptorNames">
    			<list>
    				<!-- 여러 보조 업무 들로 적용 가능 -->
    				<!-- Around Advice -->
    				<value>aspect</value>
    
    				<!-- Before Advice -->
    				<value>before</value>
    
    				<!-- 추가 -->	
    				<!-- After Throwing Advice -->
    				<value>afterThrowing</value>
    			</list>
    		</property>
    	</bean>
    
    </beans>

    • CalculatorAfterThrowing.java
    /*===============================
       CalculatorAfterThrowing.java
       - After Throwing Advice 구성
    =============================== */
    
    package com.test.spr;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.aop.ThrowsAdvice;
    
    //-- 선언된 메소드가 없는 인터페이스 상속
    public class CalculatorAfterThrowing implements ThrowsAdvice 
    {
    	// 던져진 예외를 수용할 수 있는 형태의 메소드 정의
    	//-- 하지만 이 또한 메소드이기 때문에 throwable 로 던져줘야함
    	public void afterThrowing(IllegalArgumentException e) throws Throwable
    	{
    		Log log = LogFactory.getLog(this.getClass());
    		log.info("After Throwing Advice 수행 -------------------------");
    		log.info("주 업무 실행과정에서 예외 발생 시 처리되는 사후 업무");
    		log.info(e.toString());
    		log.info("------------------------- After Throwing Advice 수행");
    	}
    }

    728x90
Designed by planet-si