Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
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
Archives
Today
Total
관리 메뉴

Everything has an expiration date

[Spring] 20240109 [프로그램 소스] 본문

[Spring]/Program source (Spring)

[Spring] 20240109 [프로그램 소스]

Jelly-fish 2024. 1. 9. 15:01

 

SpringPrj05 - com.test.spr


 

■■■ AOP 개념 실습 01 ■■■

※ AOP 기법을 적용하기 이전 형태로 개념 실습 

○ 실습 성격 및 주요사항
   1. 콘솔 프로젝트
   2. 기본적인 산술 연산 처리 
   3. AOP 기법을 적용하지 않은 상태로 
      보조 업무(시간 측정, 로그 기록 처리)를 수행하는 실습을 진행한다.
   4. SpringPrj05
   5. 로그 및 스톱워치 기능 사용을 위해 관련 jar 파일을 등록하여
      실습을 진행할 수 있도록 한다.

( * 스프링 AOP를 적용하려는 api가 아니라
    로그나 스톱워치를 등록하기 위한 api이다. )
○ 등록해야 할 jar 파일
   - 경로 1  → C:\s-f-3.0.2-with-docs\dist
     ·파일1 → org.springframework.core-3.0.2.RELEASE.jar
   - 경로 2  → C:\s-f-3.0.2-dependencies\org.apache.commons         \com.springsource.org.apache.commons.logging\1.1.1
     ·파일2 → com.springsource.org.apache.commons.logging-1.1.1.jar

○ 물리적 파일 구성
   1. Calculator.java → 인터페이스
   2. CalculatorImpl.java → 클래스. 주 업무, 보조 업무 적용.
   3. Main.java → 클래스. main() 메소드를 포함하는 클래스.

 

Calculator.java (인터페이스)

 

/*========================
    Calculator.java
    - 인터페이스
=========================*/
package com.test.spr;

// ※ 스프링 AOP 기법을 적용하기 위해서는
//    대상 객체가 인터페이스를 구현하고 있어야 한다.
public interface Calculator
{
	// 주 업무(core concern)진행을 위한 (추상) 메소드 선언
	//-- 덧셈, 뺄셈, 곱셈, 나눗셈
	public int add(int x, int y);
	public int sub(int x, int y);
	public int mul(int x, int y);
	public int div(int x, int y);
}

 


CalculatorImpl.java

 

/*================================================
    CalculatorImpl.java
    - 클래스.
    - Calculator 인터페이스를 구현하는 클래스.
    - 주 업무, 보조 업무가 함께 처리되는 형태.
==================================================*/

package com.test.spr;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.StopWatch;

public class CalculatorImpl implements Calculator
{
	// 주 업무(core concern) 진행을 위한 메소드 구현
	
	
	@Override
	public int add(int x, int y)
	{
		int result = 0;
		
		// 보조 업무(cross-cutting concern) 설정
		//-- 시간 측정 시작 및 로그 기록 처리
		Log log = LogFactory.getLog(this.getClass());
		//-- 현재 우리가 사용하고 있는 CalculatorImpl.java 클래스에서
		//   로그를 생성해 내겠다는 의미이다.
		//   [LogFactory] : Log를 생성해 내는 공장과도 같다. 
		//                  여러 개의 log를 간편하게 생성한다.
		//   getLog() → static 메소드, Log를 반환한다.
		
		StopWatch sw = new StopWatch();
		sw.start();
		log.info("처리 시간 측정 시작 -------------");
		//-- [log.info()] : 로그 정보를 등록하는 것이다.
		
		
		// 주 업무(core concern) 실행 내용
		result = x + y;
		
		System.out.printf("%d + %d = %d%n", x, y, result);
		
		
		// 보조 업무(cross-cutting concern) 설정
		//-- 시간 측정 종료 및 로그 기록 처리
		sw.stop();
		log.info("처리 시간 측정 종료 -------------");
		log.info(String.format("경과시간 : %s/10000초", sw.getTotalTimeMillis()));
		
		//★★★★★★★★★★★★★★★★★★★★★★★★
		// 로그 기록남기기(『보조업무』)를
		// 『주 업무』의 앞에서도 하고 뒤에서도 하므로
		// Around Advice 를 하고 있다고 볼 수 있다.
		//★★★★★★★★★★★★★★★★★★★★★★★★
		
		return result;
	}

	@Override
	public int sub(int x, int y)
	{
		int result = 0;
	
		// 보조 업무(cross-cutting concern) 설정
		//-- 시간 측정 시작 및 로그 기록 처리
		Log log = LogFactory.getLog(this.getClass());
		StopWatch sw = new StopWatch();
		sw.start();
		log.info("처리 시간 측정 시작 -------------");
		
		
		// 주 업무(core concern) 실행 내용
		result = x - y;
		
		System.out.printf("%d - %d = %d%n", x, y, result);

		
		// 보조 업무(cross-cutting concern) 설정
		//-- 시간 측정 종료 및 로그 기록 처리
		sw.stop();
		log.info("처리 시간 측정 종료 -------------");
		log.info(String.format("경과시간 : %s/10000초", sw.getTotalTimeMillis()));
		return result;
	}

	@Override
	public int mul(int x, int y)
	{
		int result = 0;
		
		// 보조 업무(cross-cutting concern) 설정
		//-- 시간 측정 시작 및 로그 기록 처리
		Log log = LogFactory.getLog(this.getClass());
		StopWatch sw = new StopWatch();
		sw.start();
		log.info("처리 시간 측정 시작 -------------");
		
		
		// 주 업무(core concern) 실행 내용
		result = x * y;
		
		System.out.printf("%d * %d = %d%n", x, y, result);
		
		// 보조 업무(cross-cutting concern) 설정
		//-- 시간 측정 종료 및 로그 기록 처리
		sw.stop();
		log.info("처리 시간 측정 종료 -------------");
		log.info(String.format("경과시간 : %s/10000초", sw.getTotalTimeMillis()));
		
		return result;
	}

	@Override
	public int div(int x, int y)
	{
		int result = 0;
		
		// 보조 업무(cross-cutting concern) 설정
		//-- 시간 측정 시작 및 로그 기록 처리
		Log log = LogFactory.getLog(this.getClass());
		StopWatch sw = new StopWatch();
		sw.start();
		log.info("처리 시간 측정 시작 -------------");

		// 주 업무(core concern) 실행 내용
		result = x / y;

		System.out.printf("%d / %d = %d%n", x, y, result);
		
		
		// 보조 업무(cross-cutting concern) 설정
		//-- 시간 측정 종료 및 로그 기록 처리
		sw.stop();
		log.info("처리 시간 측정 종료 -------------");
		log.info(String.format("경과시간 : %s/10000초", sw.getTotalTimeMillis()));
		
		
		return result;
	}
	
}

 


Main.java

 

/*============================================
    Main.java
    - main() 메소드가 포함된 테스트 클래스
==============================================*/
package com.test.spr;

public class Main
{
	public static void main(String[] args)
	{
		// 주 업무 실행을 할 수 있는 객체 준비
		// 인터페이스 변수 = new 인터페이스구현클래스();
		// List list = new ArrayList();
		
		Calculator cal = new CalculatorImpl();
		
		// 주 업무 실행에 대한 테스트
		int add = cal.add(10,  20);
		System.out.println(add);
		
		int sub = cal.sub(10, 20);
		System.out.println(sub);
		
		int multi = cal.mul(10, 20);
		System.out.println(multi);
		
		int div = cal.div(10, 20);
		System.out.println(div);
	}
}

 

[실행 결과 콘솔창]

 


 

SpringPrj06 - com.test.spr


■■■ AOP 개념 실습 02 ■■■

※ AOP 기법을 적용하는 형태로 개념 실습 

○ 실습 성격 및 주요사항
   1. 콘솔 프로젝트
   2. 기본적인 산술 연산 처리 
   3. AOP 기법을 적용하여
      보조 업무(시간 측정, 로그 기록 처리)를 수행하는 실습을 진행한다.
   4. SpringPrj06
   5. 로그 및 스톱워치 기능 사용을 위해 관련 jar 파일을 등록하여
      실습을 진행할 수 있도록 한다.

( * 스프링 AOP를 적용하려는 api가 아니라
    로그나 스톱워치를 등록하기 위한 api이다. )

○ 등록해야 할 jar 파일
   - 경로 1  → C:\s-f-3.0.2-with-docs\dist
     ·파일1 → org.springframework.core-3.0.2.RELEASE.jar
   - 경로 2  → C:\s-f-3.0.2-dependencies\org.apache.commons         \com.springsource.org.apache.commons.logging\1.1.1
     ·파일2 → com.springsource.org.apache.commons.logging-1.1.1.jar

○ 물리적 파일 구성
   1. Calculator.java → 인터페이스(기존 소스코드 그대로 활용)
   
   2. CalculatorProxy.java → 프록시(proxy) 클래스
      (추가~!!!)                   보조 업무 적용 및 주 업무 호출 과정

   3. CalculatorImpl.java → 클래스. 주 업무 적용.
   4. Main.java → 클래스. main() 메소드를 포함하는 클래스.

 

Calculator.java

 

/*========================
    Calculator.java
    - 인터페이스
=========================*/
package com.test.spr;

// ※ 스프링 AOP 기법을 적용하기 위해서는
//    대상 객체가 인터페이스를 구현하고 있어야 한다.
public interface Calculator
{
	// 주 업무(core concern)진행을 위한 (추상) 메소드 선언
	//-- 덧셈, 뺄셈, 곱셈, 나눗셈
	public int add(int x, int y);
	public int sub(int x, int y);
	public int mul(int x, int y);
	public int div(int x, int y);
}

CalculatorProxy.java

 

/*========================================
   CalculatorProxy.java
   - 프록시 클래스.
   - 보조 업무 적용 및 주 업무 호출 과정.
==========================================*/

// ※ Proxy 클래스를 만드는 여러가지 방법들 중
//    비교적 쉽고 직관적인 방법은
//    InvocationHandler 인터페이스를 구현하는 클래스를 만드는 것이다.


package com.test.spr;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.StopWatch;

public class CalculatorProxy implements InvocationHandler
{
	// 주요 속성 구성
	
	// target → 가짜가... 진짜 행세를 하게 될 대상!
	private Object target;
	
	// 생성자 정의
	
	public CalculatorProxy(Object target)
	{
		this.target = target;
	}

	// 보조 업무 적용 및 주 업무 호출 과정 추가
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
	{
		Object result = null;
		
		// 보조 업무(cross-cutting concern) 설정
		//-- 시간 측정 및 로그 기록(Around Advice)
		Log log = LogFactory.getLog(this.getClass());
		StopWatch sw = new StopWatch();
		sw.start();
		log.info("처리 시간 측정 시작-----------------");
		
		
		// 주 업무(core concern) 실행 내용
		result = method.invoke(target, args);
		// target이 더욱 진짜 행세를 잘 할 수 있도록 
		// 진짜가 갖고 있는 요소들을 넣어주는 것.

		
		// 보조 업무(cross-cutting concern) 설정
		//-- 시간 측정 종료 및 로그 기록(Around Advice)
		sw.stop();
		log.info("처리 시간 측정 종료-----------------");
		log.info(String.format("경과시간 : %s/10000초", sw.getTotalTimeMillis()));
		
		return result;
		
	}
	
	
	
	
}

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) 실행 내용
		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;
			
		// 주 업무(core concern) 실행 내용
		result = x - y;
		
		System.out.printf("%d - %d = %d%n", x, y, result);

		return result;
	}

	@Override
	public int mul(int x, int y)
	{
		int result = 0;
				
		// 주 업무(core concern) 실행 내용
		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;
		
		// 주 업무(core concern) 실행 내용
		result = x / y;

		System.out.printf("%d / %d = %d%n", x, y, result);
			
		return result;
	}
	
}

 

Main.java

 

/*============================================
    Main.java
    - main() 메소드가 포함된 테스트 클래스
==============================================*/
package com.test.spr;

import java.lang.reflect.Proxy;

public class Main
{
	public static void main(String[] args)
	{
		// 주 업무 실행을 할 수 있는 객체 준비
		// 인터페이스 변수 = new 인터페이스구현클래스();
		// List list = new ArrayList();
		
		Calculator cal = new CalculatorImpl();
		
		// 주 업무 실행에 대한 테스트
		// -------------------------------- → AOP 기법 적용 전
		/*
		int add = cal.add(10,  20);
		System.out.println(add);
		
		int sub = cal.sub(10, 20);
		System.out.println(sub);
		
		int multi = cal.mul(10, 20);
		System.out.println(multi);
		
		int div = cal.div(10, 20);
		System.out.println(div);
		*/
		
		// 주 업무 실행에 대한 테스트
		// -------------------------------- → AOP 기법 적용 후
		
		Calculator proxy = (Calculator)Proxy.newProxyInstance
							( cal.getClass().getClassLoader() //-- [loader] : 주 업무 실행 클래스에 대한 정보 전달(제공) 
							, cal.getClass().getInterfaces()  //-- [interfaces] : 주 업무 실행 클래스의 인터페이스에 대한 정보 전달(제공)
							, new CalculatorProxy(cal)        //-- [h] : 보조 업무 실행 클래스에 대한 정보 전달(제공)
							);
			
		// ①
		// cal(객체).getClass() : 객체의 설계도 → 이를 로드해야함.
		// cal(객체).getClass().getClassLoader() : 진짜(별 객체)의 클래스를 로드
		// ② 진짜에 해당하는 인터페이스를 가져와서 이를 흉내내자!!
		// ③ 프록시가 따라해야 할 객체를 매개변수로 넘겨준다.
		
		// ==============================================================
		// 모든 정보가 구성이 된 후에는, 『Proxy.newProxyInstance』에서
		// 흉내내기를 완료한 가짜 객체가 생성되므로
		// 이를 반환받아서 흉내내려고 했던 타입의 객체로 받아낸다.
		// ==============================================================
		
		
		int add = proxy.add(10,  20);
		System.out.println(add);
		
		int sub = proxy.sub(10, 20);
		System.out.println(sub);
		
		int multi = proxy.mul(10, 20);
		System.out.println(multi);
		
		int div = proxy.div(10, 20);
		System.out.println(div);
		
		
		
		
	}
}

 

 

[실행 결과 콘솔창]

 


 

SpringPrj07 - com.test.spr


 


■■■ AOP 개념 실습 03 ■■■

※ Spring AOP 기법을 적용하는 형태로 개념 실습 

○ 실습 성격 및 주요사항
   1. 콘솔 프로젝트
   2. 기본적인 산술 연산 처리 
   3. Spring AOP 기법을 적용하여  
      보조 업무(시간 측정, 로그 기록 처리)를 수행하는 실습을 진행한다.
   4. SpringPrj07
   5. 로그 및 스톱워치 기능 사용을 위해 관련 jar 파일을 등록하여
      실습을 진행할 수 있도록 한다.

   
○ 등록해야 할 jar 파일
   (로그 및 스톱워치 사용을 위해 등록해야 할 jar 파일
    + 스프링 AOP 기법을 적용하기 위한 jar 파일)

   - 경로 1  → C:\s-f-3.0.2-with-docs\dist

     ·파일 1 → org.springframework.asm-3.0.2.RELEASE.jar
     ·파일 2 → org.springframework.beans-3.0.2.RELEASE.jar
     ·파일 3 → org.springframework.context-3.0.2.RELEASE.jar
     ·파일 4 → org.springframework.core-3.0.2.RELEASE.jar
     ·파일 5 → org.springframework.expression-3.0.2.RELEASE.jar
     ·파일 6 → org.springframework.aop-3.0.2.RELEASE.jar

   - 경로 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



○ 물리적 파일 구성
   1. Calculator.java → 인터페이스(기존 소스코드 그대로 활용)
   
   2. CalculatorAspect.java → 보조 업무 클래스
      (추가~!!!)                   보조 업무 적용 및 주 업무 호출 과정

   3. CalculatorImpl.java → 클래스. 주 업무 적용. (기존 소스코드 그대로 활용)

   4. Main.java → 클래스. main() 메소드를 포함하는 클래스.

   5. config.xml → 스프링 환경 설정 파일.
      (추가~!!!)                   객체 생성 및 DI 설정.


 

 

Calculator.java

 

/*========================
    Calculator.java
    - 인터페이스
=========================*/
package com.test.spr;

// ※ 스프링 AOP 기법을 적용하기 위해서는
//    대상 객체가 인터페이스를 구현하고 있어야 한다.
public interface Calculator
{
	// 주 업무(core concern)진행을 위한 (추상) 메소드 선언
	//-- 덧셈, 뺄셈, 곱셈, 나눗셈
	public int add(int x, int y);
	public int sub(int x, int y);
	public int mul(int x, int y);
	public int div(int x, int y);
}

CalculatorAspect.java 

 

/*=====================================
   CalculatorAspect.java
   - 보조 업무 수행 클래스.
   - 보조 업무 적용 및 주 업무 호출
=======================================*/

// ※ Spring AOP Proxy 클래스를 만들기 위해서
//    MethodIntercepter 인터페이스를 구현하는 클래스로 설계한다.



package com.test.spr;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.StopWatch;

public class CalculatorAspect implements MethodInterceptor
{

	@Override
	public Object invoke(MethodInvocation method) throws Throwable
	{
		
		Object result = null;
		
		// 보조 업무(cross-cutting concern) 설정
		//-- 시간 측정 시작 및 로그 기록(Around Advice)
		Log log = LogFactory.getLog(this.getClass());
		StopWatch sw = new StopWatch();
		sw.start();
		log.info("처리 시간 측정 시작---------------");
		
		// 주 업무(core concern) 호출 부분~!!!
		result = method.proceed();
		
		
		// 보조 업무(cross-cutting concern) 설정
		//-- 시간 측정 종료 및 로그 기록(Around Advice)
		sw.stop();
		log.info("처리 시간 측정 종료----------------");
		log.info(String.format("경과시간: %s/10000초", sw.getTotalTimeMillis()));
		
		return null;
		
	}
	
}

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) 실행 내용
		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;
			
		// 주 업무(core concern) 실행 내용
		result = x - y;
		
		System.out.printf("%d - %d = %d%n", x, y, result);

		return result;
	}

	@Override
	public int mul(int x, int y)
	{
		int result = 0;
				
		// 주 업무(core concern) 실행 내용
		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;
		
		// 주 업무(core concern) 실행 내용
		result = x / y;

		System.out.printf("%d / %d = %d%n", x, y, result);
			
		return result;
	}
	
}

config.xml (applicationContext.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>
	
	<!-- 스프링이 제공하는 가짜 객체(Proxy) 클래스의 객체 생성 및 관리를 위한 정보 전달 -->
	<!-- → 『ProxyFactoryBean』 -->
	<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
	
		<!-- 주 업무 클래스의 인터페이스 정보 제공 -->
		<!-- → 『proxyInterfaces』 -->
		<property name="proxyInterfaces">
			<list>
				<value>com.test.spr.Calculator</value>
				<!--===========================================================-->
				<!-- bean 구성을 못하는 interface 이기 때문에 -->
				<!-- 위와 같이 클래스의 주소와 클래스명을 작성해 준 것이다. -->
				<!--===========================================================-->
			</list>
		</property>
		
		
		<!-- 주 업무 클래스의 객체 정보 제공 -->
		<!-- → 『target』 -->
		<property name="target" ref="cal"></property>		
		
		<!-- 보조 업무 클래스의 객체 정보 제공 -->
		<!-- → 『interceptorNames』 : 가로챈 아이들의 이름들... -->
		<property name="interceptorNames">
			<list>
				<value>aspect</value>
			</list>
		</property>
		
		
	</bean>
	
	
	
	
</beans>

Main.java

 

/*============================================
    Main.java
    - main() 메소드가 포함된 테스트 클래스
==============================================*/
package com.test.spr;

import java.lang.reflect.Proxy;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main
{
	public static void main(String[] args)
	{
		// 주 업무 실행을 할 수 있는 객체 준비
		// 인터페이스 변수 = new 인터페이스구현클래스();
		// List list = new ArrayList();
		
		// Calculator cal = new CalculatorImpl();
		
		// 주 업무 실행에 대한 테스트
		// -------------------------------- → AOP 기법 적용 전
		/*
		int add = cal.add(10,  20);
		System.out.println(add);
		
		int sub = cal.sub(10, 20);
		System.out.println(sub);
		
		int multi = cal.mul(10, 20);
		System.out.println(multi);
		
		int div = cal.div(10, 20);
		System.out.println(div);
		*/
		
		// 주 업무 실행에 대한 테스트
		// -------------------------------- → AOP 기법 적용 후
		
		/*
		Calculator proxy = (Calculator)Proxy.newProxyInstance
							( cal.getClass().getClassLoader() //-- [loader] : 주 업무 실행 클래스에 대한 정보 전달(제공) 
							, cal.getClass().getInterfaces()  //-- [interfaces] : 주 업무 실행 클래스의 인터페이스에 대한 정보 전달(제공)
							, new CalculatorProxy(cal)        //-- [h] : 보조 업무 실행 클래스에 대한 정보 전달(제공)
							);
			
		// ①
		// cal(객체).getClass() : 객체의 설계도 → 이를 로드해야함.
		// cal(객체).getClass().getClassLoader() : 진짜(별 객체)의 클래스를 로드
		// ② 진짜에 해당하는 인터페이스를 가져와서 이를 흉내내자!!
		// ③ 프록시가 따라해야 할 객체를 매개변수로 넘겨준다.
		
		// ==============================================================
		// 모든 정보가 구성이 된 후에는, 『Proxy.newProxyInstance』에서
		// 흉내내기를 완료한 가짜 객체가 생성되므로
		// 이를 반환받아서 흉내내려고 했던 타입의 객체로 받아낸다.
		// ==============================================================
		
		
		int add = proxy.add(10,  20);
		System.out.println(add);
		
		int sub = proxy.sub(10, 20);
		System.out.println(sub);
		
		int multi = proxy.mul(10, 20);
		System.out.println(multi);
		
		int div = proxy.div(10, 20);
		System.out.println(div);
		
		*/
		// 주 업무 실행에 대한 테스트
		// ------------------------------------- → Spring AOP 기법 적용 후
		
		ApplicationContext context = new ClassPathXmlApplicationContext("config.xml");
		
		//Calculator cal = new CalculatorImpl();
		//Calculator cal = (Calculator) 객체 수신;
		
		Calculator cal = context.getBean("proxy", Calculator.class);
		
		
		int add = cal.add(10,  20);
		System.out.println(add);
		
		int sub = cal.sub(10, 20);
		System.out.println(sub);
		
		int multi = cal.mul(10, 20);
		System.out.println(multi);
		
		int div = cal.div(10, 20);
		System.out.println(div);
		
	}
}

 

 

[실행 결과 콘솔창]

 


 

 

SpringPrj08 - com.test.spr


 


■■■ AOP 개념 실습 04 ■■■

※ AOP Advice

   ·Advice
     언제 어떤 공통 관심 사항(보조 업무, cross-cutting concern)을
     적용할지 결정하는 방법.
     Before Advice, After Advice, Around Advice 등이 있다.

   ·Before Advice
     보조 업무가 주 업무 실행 전에 수행되는 경우.
   ·After Advice
     보조 업무가 주 업무 실행 후에 수행되는 경우.
   ·Around Advice
     보조 업무가 주 업무 실행 전과 후에 수행되는 경우.


○ 실습 성격 및 주요사항
   1. 콘솔 프로젝트
   2. 기본적인 산술 연산 처리 
   3. Spring AOP 기법을 Advice 로 구분하여
      보조 업무(시간 측정, 로그 기록 처리)를 수행하는 실습을 진행한다.
   4. SpringPrj08
   5. 로그 및 스톱워치 기능 사용을 위해 관련 jar 파일을 등록하여 실습을 진행할 수 있도록 한다.
   6. 추가로 Spring AOP 기법을 적용하기 위한 jar 파일을 등록하여 실습을 진행할 수 있도록 한다.

   
○ 등록해야 할 jar 파일
   (로그 및 스톱워치 사용을 위해 등록해야 할 jar 파일
    + 스프링 AOP 기법을 적용하기 위한 jar 파일)

   - 경로 1  → C:\s-f-3.0.2-with-docs\dist
     ·파일 1 → org.springframework.aop-3.0.2.RELEASE.jar
     ·파일 2 → org.springframework.asm-3.0.2.RELEASE.jar
     ·파일 3 → org.springframework.beans-3.0.2.RELEASE.jar
     ·파일 4 → org.springframework.context-3.0.2.RELEASE.jar
     ·파일 5 → org.springframework.core-3.0.2.RELEASE.jar
     ·파일 6 → org.springframework.expression-3.0.2.RELEASE.jar

   - 경로 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



○ 물리적 파일 구성
   1. Calculator.java → 인터페이스(기존 소스코드 그대로 활용)
   
   2. CalculatorAspect.java → 보조 업무 클래스
                                   보조 업무 적용 및 주 업무 호출 과정

   3. CalculatorImpl.java → 클래스. 주 업무 적용. (기존 소스코드 그대로 활용)

   4. Main.java → 클래스. main() 메소드를 포함하는 클래스.

   5. config.xml → 스프링 환경 설정 파일.
                                   객체 생성 및 DI 설정.

   6. CalculatorBeforeAdvice.java → 추가. BeforeAdvice





 

 

Calculator.java

 

/*========================
    Calculator.java
    - 인터페이스
=========================*/
package com.test.spr;

// ※ 스프링 AOP 기법을 적용하기 위해서는
//    대상 객체가 인터페이스를 구현하고 있어야 한다.
public interface Calculator
{
	// 주 업무(core concern)진행을 위한 (추상) 메소드 선언
	//-- 덧셈, 뺄셈, 곱셈, 나눗셈
	public int add(int x, int y);
	public int sub(int x, int y);
	public int mul(int x, int y);
	public int div(int x, int y);
}

CalculatorAspect.java
/*=====================================
   CalculatorAspect.java
   - 보조 업무 수행 클래스.
   - 보조 업무 적용 및 주 업무 호출
=======================================*/

// ※ Spring AOP Proxy 클래스를 만들기 위해서
//    MethodIntercepter 인터페이스를 구현하는 클래스로 설계한다.



package com.test.spr;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.StopWatch;

public class CalculatorAspect implements MethodInterceptor
{

	@Override
	public Object invoke(MethodInvocation method) throws Throwable
	{
		
		Object result = null;
		
		// 보조 업무(cross-cutting concern) 설정
		//-- 시간 측정 시작 및 로그 기록(Around Advice)
		Log log = LogFactory.getLog(this.getClass());
		StopWatch sw = new StopWatch();
		sw.start();
		log.info("처리 시간 측정 시작---------------");
		
		// 주 업무(core concern) 호출 부분~!!!
		result = method.proceed();
		
		
		// 보조 업무(cross-cutting concern) 설정
		//-- 시간 측정 종료 및 로그 기록(Around Advice)
		sw.stop();
		log.info("처리 시간 측정 종료----------------");
		log.info(String.format("경과시간: %s/10000초", sw.getTotalTimeMillis()));
		
		return result;
		
	}
	
}

 


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) 실행 내용
		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;
			
		// 주 업무(core concern) 실행 내용
		result = x - y;
		
		System.out.printf("%d - %d = %d%n", x, y, result);

		return result;
	}

	@Override
	public int mul(int x, int y)
	{
		int result = 0;
				
		// 주 업무(core concern) 실행 내용
		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;
		
		// 주 업무(core concern) 실행 내용
		result = x / y;

		System.out.printf("%d / %d = %d%n", x, y, result);
			
		return result;
	}
	
}

Main.java
/*============================================
    Main.java
    - main() 메소드가 포함된 테스트 클래스
==============================================*/
package com.test.spr;

import java.lang.reflect.Proxy;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main
{
	public static void main(String[] args)
	{
		// 주 업무 실행을 할 수 있는 객체 준비
		// 인터페이스 변수 = new 인터페이스구현클래스();
		// List list = new ArrayList();
		
		// Calculator cal = new CalculatorImpl();
		
		// 주 업무 실행에 대한 테스트
		// -------------------------------- → AOP 기법 적용 전
		/*
		int add = cal.add(10,  20);
		System.out.println(add);
		
		int sub = cal.sub(10, 20);
		System.out.println(sub);
		
		int multi = cal.mul(10, 20);
		System.out.println(multi);
		
		int div = cal.div(10, 20);
		System.out.println(div);
		*/
		
		// 주 업무 실행에 대한 테스트
		// -------------------------------- → AOP 기법 적용 후
		
		/*
		Calculator proxy = (Calculator)Proxy.newProxyInstance
							( cal.getClass().getClassLoader() //-- [loader] : 주 업무 실행 클래스에 대한 정보 전달(제공) 
							, cal.getClass().getInterfaces()  //-- [interfaces] : 주 업무 실행 클래스의 인터페이스에 대한 정보 전달(제공)
							, new CalculatorProxy(cal)        //-- [h] : 보조 업무 실행 클래스에 대한 정보 전달(제공)
							);
			
		// ①
		// cal(객체).getClass() : 객체의 설계도 → 이를 로드해야함.
		// cal(객체).getClass().getClassLoader() : 진짜(별 객체)의 클래스를 로드
		// ② 진짜에 해당하는 인터페이스를 가져와서 이를 흉내내자!!
		// ③ 프록시가 따라해야 할 객체를 매개변수로 넘겨준다.
		
		// ==============================================================
		// 모든 정보가 구성이 된 후에는, 『Proxy.newProxyInstance』에서
		// 흉내내기를 완료한 가짜 객체가 생성되므로
		// 이를 반환받아서 흉내내려고 했던 타입의 객체로 받아낸다.
		// ==============================================================
		
		
		int add = proxy.add(10,  20);
		System.out.println(add);
		
		int sub = proxy.sub(10, 20);
		System.out.println(sub);
		
		int multi = proxy.mul(10, 20);
		System.out.println(multi);
		
		int div = proxy.div(10, 20);
		System.out.println(div);
		
		*/
		// 주 업무 실행에 대한 테스트
		// ------------------------------------- → Spring AOP 기법 적용 후
		
		ApplicationContext context = new ClassPathXmlApplicationContext("config.xml");
		
		//Calculator cal = new CalculatorImpl();
		//Calculator cal = (Calculator) 객체 수신;
		
		Calculator cal = context.getBean("proxy", Calculator.class);
		
		
		int add = cal.add(10,  20);
		System.out.println(add);
		
		int sub = cal.sub(10, 20);
		System.out.println(sub);
		
		int multi = cal.mul(10, 20);
		System.out.println(multi);
		
		int div = cal.div(10, 20);
		System.out.println(div);
		
	}
}

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~!!! -->
	<!-- 추가~!!! -->
	<!-- CalculatorBefoerAdvice 클래스의 객체 생성 및 관리를 위한 정보 전달 -->
	<bean id="before" class="com.test.spr.CalculatorBeforeAdvice"></bean>
	
	
	
	
	
	
	<!-- 스프링이 제공하는 가짜 객체(Proxy) 클래스의 객체 생성 및 관리를 위한 정보 전달 -->
	<!-- → 『ProxyFactoryBean』 -->
	<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
	
		<!-- 주 업무 클래스의 인터페이스 정보 제공 -->
		<!-- → 『proxyInterfaces』 -->
		<property name="proxyInterfaces">
			<list>
				<value>com.test.spr.Calculator</value>
				<!--===========================================================-->
				<!-- bean 구성을 못하는 interface 이기 때문에 -->
				<!-- 위와 같이 클래스의 주소와 클래스명을 작성해 준 것이다. -->
				<!--===========================================================-->
			</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;
import org.springframework.util.StopWatch;

public class CalculatorBeforeAdvice implements MethodBeforeAdvice
{

	@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 수행 ");
		
		
		
	}
	
}

 

[실행 결과 콘솔창]

 


 


■■■ AOP 개념 실습 05 ■■■

※ AOP Advice

   ·Advice
     언제 어떤 공통 관심 사항(보조 업무, cross-cutting concern)을
     적용할지 결정하는 방법.
     Before Advice, After Advice, Around Advice 등이 있다.

   ·Before Advice
     보조 업무가 주 업무 실행 전에 수행되는 경우.
   ·After Advice
     보조 업무가 주 업무 실행 후에 수행되는 경우.
   ·Around Advice
     보조 업무가 주 업무 실행 전과 후에 수행되는 경우.


○ 실습 성격 및 주요사항
   1. 콘솔 프로젝트
   2. 기본적인 산술 연산 처리 
   3. Spring AOP 기법을 Advice 로 구분하여
      보조 업무(시간 측정, 로그 기록 처리)를 수행하는 실습을 진행한다.
   4. SpringPrj09
   5. 로그 및 스톱워치 기능 사용을 위해 관련 jar 파일을 등록하여 실습을 진행할 수 있도록 한다.
   6. 추가로 Spring AOP 기법을 적용하기 위한 jar 파일을 등록하여 실습을 진행할 수 있도록 한다.

   
○ 등록해야 할 jar 파일
   (로그 및 스톱워치 사용을 위해 등록해야 할 jar 파일
    + 스프링 AOP 기법을 적용하기 위한 jar 파일)

   - 경로 1  → C:\s-f-3.0.2-with-docs\dist
     ·파일 1 → org.springframework.aop-3.0.2.RELEASE.jar
     ·파일 2 → org.springframework.asm-3.0.2.RELEASE.jar
     ·파일 3 → org.springframework.beans-3.0.2.RELEASE.jar
     ·파일 4 → org.springframework.context-3.0.2.RELEASE.jar
     ·파일 5 → org.springframework.core-3.0.2.RELEASE.jar
     ·파일 6 → org.springframework.expression-3.0.2.RELEASE.jar

   - 경로 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



○ 물리적 파일 구성
   1. Calculator.java → 인터페이스(기존 소스코드 그대로 활용)
   
   2. CalculatorAspect.java → 보조 업무 클래스
                                   보조 업무 적용 및 주 업무 호출 과정

   3. CalculatorImpl.java → 클래스. 주 업무 적용. (기존 소스코드 그대로 활용)

   4. Main.java → 클래스. main() 메소드를 포함하는 클래스.

   5. config.xml → 스프링 환경 설정 파일.
                                   객체 생성 및 DI 설정.

   6. CalculatorBeforeAdvice.java → 추가. Before Advice

   7. CalculatorAfterThrowing.java → 추가. After Throwing Advice

 

Calculator.java

 

/*========================
    Calculator.java
    - 인터페이스
=========================*/
package com.test.spr;

// ※ 스프링 AOP 기법을 적용하기 위해서는
//    대상 객체가 인터페이스를 구현하고 있어야 한다.
public interface Calculator
{
	// 주 업무(core concern)진행을 위한 (추상) 메소드 선언
	//-- 덧셈, 뺄셈, 곱셈, 나눗셈
	public int add(int x, int y);
	public int sub(int x, int y);
	public int mul(int x, int y);
	public int div(int x, int y);
}

CalculatorAspect.java
/*=====================================
   CalculatorAspect.java
   - 보조 업무 수행 클래스.
   - 보조 업무 적용 및 주 업무 호출
=======================================*/

// ※ Spring AOP Proxy 클래스를 만들기 위해서
//    MethodIntercepter 인터페이스를 구현하는 클래스로 설계한다.



package com.test.spr;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.StopWatch;

public class CalculatorAspect implements MethodInterceptor
{

	@Override
	public Object invoke(MethodInvocation method) throws Throwable
	{
		
		Object result = null;
		
		// 보조 업무(cross-cutting concern) 설정
		//-- 시간 측정 시작 및 로그 기록(Around Advice)
		Log log = LogFactory.getLog(this.getClass());
		StopWatch sw = new StopWatch();
		sw.start();
		log.info("처리 시간 측정 시작---------------");
		
		// 주 업무(core concern) 호출 부분~!!!
		result = method.proceed();
		
		
		// 보조 업무(cross-cutting concern) 설정
		//-- 시간 측정 종료 및 로그 기록(Around Advice)
		sw.stop();
		log.info("처리 시간 측정 종료----------------");
		log.info(String.format("경과시간: %s/10000초", sw.getTotalTimeMillis()));
		
		return result;
		
	}
	
}

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) 실행 내용
		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;
			
		// 주 업무(core concern) 실행 내용
		result = x - y;
		
		System.out.printf("%d - %d = %d%n", x, y, result);

		return result;
	}

	@Override
	public int mul(int x, int y)
	{
		int result = 0;
				
		// 주 업무(core concern) 실행 내용
		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;
		
		// 주 업무(core concern) 실행 내용
		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>
	
	
	<!-- CalculatorBefoerAdvice 클래스의 객체 생성 및 관리를 위한 정보 전달 -->
	<bean id="before" class="com.test.spr.CalculatorBeforeAdvice"></bean>
	
	<!-- check~!!! -->
	<!-- 추가 -->
	<!-- CalculatorAfterThrowing 클래스의 객체 생성 및 관리를 위한 정보 전달  -->
	<bean id="afterThrowing" class="com.test.spr.CalculatorAfterThrowing"></bean>
	
	
	
	<!-- 스프링이 제공하는 가짜 객체(Proxy) 클래스의 객체 생성 및 관리를 위한 정보 전달 -->
	<!-- → 『ProxyFactoryBean』 -->
	<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
	
		<!-- 주 업무 클래스의 인터페이스 정보 제공 -->
		<!-- → 『proxyInterfaces』 -->
		<property name="proxyInterfaces">
			<list>
				<value>com.test.spr.Calculator</value>
				<!--===========================================================-->
				<!-- bean 구성을 못하는 interface 이기 때문에 -->
				<!-- 위와 같이 클래스의 주소와 클래스명을 작성해 준 것이다. -->
				<!--===========================================================-->
			</list>
		</property>
		
		
		<!-- 주 업무 클래스의 객체 정보 제공 -->
		<!-- → 『target』 -->
		<property name="target" ref="cal"></property>		
		
		<!-- 보조 업무 클래스의 객체 정보 제공 -->
		<!-- → 『interceptorNames』 : 가로챈 아이들의 이름들... -->
		<property name="interceptorNames">
			<list>
			
				<!-- Around Advice -->
				<value>aspect</value>
				
				<!-- Before Advice -->
				<value>before</value>
				
				<!-- check~!!! -->
				<!-- 추가 -->
				<!-- After Throwing Advice -->
				<value>afterThrowing</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;
import org.springframework.util.StopWatch;

public class CalculatorBeforeAdvice implements MethodBeforeAdvice
{

	@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 수행 ");
		
		
		
	}
	
}

 


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;

//**********************************************************
// 주 업무에서 예외가 발생했을 때만 동작하는 클래스이므로
// 예외가 발생하도록 처리를 해야 한다. (throw new (예외명))
//**********************************************************

public class CalculatorAfterThrowing implements ThrowsAdvice
{
	//****************************************************
	// 주 업무 처리 클래스에서 인위적으로 발생시킨 에러가
	// IllegalArgumentException 이므로 매개변수로 전달.
	//****************************************************
	public void afterThrowing(IllegalArgumentException e) throws Throwable
	{
		/*
		try
		{
			
		} catch (Exception e2)
		{
		}
		*/
		
		Log log = LogFactory.getLog(this.getClass());
		log.info("After Throwing Advice ------------------------------");
		log.info("주업무 처리과정에서 예외 발생시 실행되는 사후 업무");
		log.info("------------------------------ After Throwing Advice");
		
	}
}

 


Main.java

 

/*============================================
    Main.java
    - main() 메소드가 포함된 테스트 클래스
==============================================*/
package com.test.spr;

import java.lang.reflect.Proxy;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main
{
	public static void main(String[] args)
	{
		// 주 업무 실행을 할 수 있는 객체 준비
		// 인터페이스 변수 = new 인터페이스구현클래스();
		// List list = new ArrayList();
		
		// Calculator cal = new CalculatorImpl();
		
		// 주 업무 실행에 대한 테스트
		// -------------------------------- → AOP 기법 적용 전
		/*
		int add = cal.add(10,  20);
		System.out.println(add);
		
		int sub = cal.sub(10, 20);
		System.out.println(sub);
		
		int multi = cal.mul(10, 20);
		System.out.println(multi);
		
		int div = cal.div(10, 20);
		System.out.println(div);
		*/
		
		// 주 업무 실행에 대한 테스트
		// -------------------------------- → AOP 기법 적용 후
		
		/*
		Calculator proxy = (Calculator)Proxy.newProxyInstance
							( cal.getClass().getClassLoader() //-- [loader] : 주 업무 실행 클래스에 대한 정보 전달(제공) 
							, cal.getClass().getInterfaces()  //-- [interfaces] : 주 업무 실행 클래스의 인터페이스에 대한 정보 전달(제공)
							, new CalculatorProxy(cal)        //-- [h] : 보조 업무 실행 클래스에 대한 정보 전달(제공)
							);
			
		// ①
		// cal(객체).getClass() : 객체의 설계도 → 이를 로드해야함.
		// cal(객체).getClass().getClassLoader() : 진짜(별 객체)의 클래스를 로드
		// ② 진짜에 해당하는 인터페이스를 가져와서 이를 흉내내자!!
		// ③ 프록시가 따라해야 할 객체를 매개변수로 넘겨준다.
		
		// ==============================================================
		// 모든 정보가 구성이 된 후에는, 『Proxy.newProxyInstance』에서
		// 흉내내기를 완료한 가짜 객체가 생성되므로
		// 이를 반환받아서 흉내내려고 했던 타입의 객체로 받아낸다.
		// ==============================================================
		
		
		int add = proxy.add(10,  20);
		System.out.println(add);
		
		int sub = proxy.sub(10, 20);
		System.out.println(sub);
		
		int multi = proxy.mul(10, 20);
		System.out.println(multi);
		
		int div = proxy.div(10, 20);
		System.out.println(div);
		
		*/
		// 주 업무 실행에 대한 테스트
		// ------------------------------------- → Spring AOP 기법 적용 후
		
		ApplicationContext context = new ClassPathXmlApplicationContext("config.xml");
		
		//Calculator cal = new CalculatorImpl();
		//Calculator cal = (Calculator) 객체 수신;
		
		Calculator cal = context.getBean("proxy", Calculator.class);
		
		int add = cal.add(10,  20);
		System.out.println(add);
		
		/*
		int sub = cal.sub(10, 20);
		System.out.println(sub);
		
		int multi = cal.mul(10, 20);
		System.out.println(multi);
		
		int div = cal.div(10, 20);
		System.out.println(div);
		*/
		
		// 예외 상황이 발생할 수 있도록 값을 넘기는 처리
		int add2 = cal.add(100, 200);
		System.out.println(add2);
		
		
		
	}
}

 

[실행 결과 콘솔창]