Header

  1. View current page

    정상혁의 수첩

Profile_img_60x60_08
195

Java의 Dynamic Proxy를 이용한 AOP

 

모듈화만으로는 중복을 제거하기 힘든 코드들

//시작시간기록

//로깅

//트랜잭선언

try{

//트랜잭션 시작

//핵심업무로직

//커밋

} catch (Exception e){

//트랜잭션 롤백

//로깅 logger.error("...");

//시스템 정의 Exception으로 다시 throw

}

//로깅

//종료시간기록, 수행시간 계산 로깅

 

위의 코드에서 핵심업무로직을 제외하고는 같은 코드일 경우에도 중복된 코드가 메서드마다 들어가야 하는가

 

 

공통적인 실행흐름을 가진 코드의 중복을 제거

  • 클로저 (script 언어) (참고자료6)
  • Command pattern  (참고자료8)
  • AOP 활용

 

 

대표적인 AOP framework

  • Aspect  J :
    • java 언어를 확장. Aspectj 커맨드라인 컴파일러(ajc)필요
    • annotation or XML 으로 aspect 선언
    • 가장 오랜 역사 ,풍부한 기능
    • 개발을 도와주는 도구로 이클립스 플러그인 ADJT가 있음

 

  • Asjectwertz ;
    • java언어를 확장하지 않은 일반 java클래스 사용
    • XML로 aspect 선언
    • Aspect J 1.5버전에 통합

 

  • Spring AOP
    • 기존 java 클래스의 바이트코드를 수정하지 않고 java의 Dynamic proxy이용
    • annotation or XML 으로 aspect 선언
    • Spring 2.0에서는 Aspect j의 발달한 포인트 컷 언어를 차용

 

  • JBoss AOP
    • java의 Dynamic proxy이용. 필요에 따라서 javaAssist를 통해 바이트 코드 조작.
    • annotation or XML 으로 aspect 선언
    • ejb 프로젝트에서 주로 사용

 

 

Ioc(Inversion Of Control)

Inversion Of Control

  • 프레임웍 vs라이브러리 (참고자료7)
    • 프레임웍 : 프레임웍의 코드가 유저코드를 호출. 실행흐름을 프레임웍이 제어
    • 라이브러리 :유저코드가  라이브러리를 호출. 실행흐름을 사용자가 제어

 

Dynamic proxy를 이용한 간단한 AOP의 구현

참고자료1에서 구한 소스. 첨부파일( proxy.zip )

소스

 

  1. package proxy.sample1;

    import java.lang.reflect.Proxy;
  2. import proxy.sample1.ExceptionHandler;
    import proxy.sample1.LoggingHandler;
    import proxy.sample1.emp.EmpManager;
    import proxy.sample1.emp.EmpManagerImpl;
  3. public class ProxyTest
    {
  4.     /**
         * @param args
         * @throws Exception
         */
        public static void main(String[] args) throws Exception
        {
            EmpManager managerProxy = getServerObject(); //서버 객체를 얻어온다.
            managerProxy.printGreetingMessage("This is test");
        }
  5.     /**
         * @return
         */
        private static EmpManager getServerObject() {
            ExceptionHandler exceptionHandler = new ExceptionHandler(new EmpManagerImpl());
  6.         LoggingHandler logHandler = new LoggingHandler(Proxy.newProxyInstance(EmpManager.class.getClassLoader(),
                    new Class[] { EmpManager.class }, exceptionHandler));
  7.         EmpManager managerProxy = (EmpManager) Proxy.newProxyInstance(EmpManager.class.getClassLoader(),
                    new Class[] { EmpManager.class }, logHandler);
            return managerProxy;
        }
    }

 

  1. package proxy.sample1.emp;
  2. public interface EmpManager
    {
        public void printGreetingMessage(String message) throws Exception;
    }

 

  1.  
  2. package proxy.sample1.emp;
  3. public class EmpManagerImpl implements EmpManager
    {
        public void printGreetingMessage(String message) throws Exception
        {
            System.out.println( "Hi: " + message);
  4.         throw new Exception("일부러 던진 에러 ");
  5.     }
    }

 

 

  1. package proxy.sample1;
  2. import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
  3. public class ExceptionHandler implements InvocationHandler
    {
        Object targetObject;
  4.     public ExceptionHandler(Object targetObject)
        {
            this.targetObject = targetObject;
        }
  5.     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
        {
            try
            {
                return method.invoke(targetObject, args);
            }
            catch (Throwable e)
            {
                System.out.println("----------------------------------");
                System.out.println("메소드 호출  예외발생:[" + method + "], 에러 메세지[" + e.getMessage() + "]");
                System.out.println("----------------------------------");
                return null;
            }
        }
    }

 

  1. package proxy.sample1;
  2. import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
  3. public class LoggingHandler implements InvocationHandler
    {
        Object targetObject;
  4.     public LoggingHandler(Object targetObject)
        {
            this.targetObject = targetObject;
        }
  5.     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
        {
            try
            {
                System.out.println("----------------------------------");
                System.out.println("메소드 호출 Start:[" + method + "][" + System.currentTimeMillis() + "]");
                return method.invoke(targetObject, args);
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                System.out.println("메소드 호출 End:[" + method + "][" + System.currentTimeMillis() + "]");
                System.out.println("----------------------------------");
            }
        }
    }

 

 

실행결과
  • 출력내용

 

----------------------------------
메소드 호출 Start:[public abstract void proxy.sample1.emp.EmpManager.printGreetingMessage(java.lang.String) throws java.lang.Exception][1182822105579]
Hi: This is test
----------------------------------
메소드 호출  예외발생:[public abstract void proxy.sample1.emp.EmpManager.printGreetingMessage(java.lang.String) throws java.lang.Exception], 에러 메세지[null]
----------------------------------
메소드 호출 End:[public abstract void proxy.sample1.emp.EmpManager.printGreetingMessage(java.lang.String) throws java.lang.Exception][1182822105579]
----------------------------------

 

  •  EmpManagerImpl 에는 Hi: This is test를 출력하는 코드밖에 없었음에도 앞뒤의 로그와 Exception 처리를 하는 코드가 실행되었음.

 

CGLib

 

 

참고자료

  1. J2EE(POJO)컴포넌트 만들기 - 부록:AOP를 이용한 트랜잭션 처리 (김형준) (소스 http://blog.naver.com/cookie_00/80023046477 )
  2. 마이크로소프트웨어 2005/11 테크니컬 컬럼 - 객체지향을 넘어 관점지향으로 AOP (이일민)   (http://www.zdnet.co.kr/builder/dev/java/0,39031622,39147106,00.htm )
  3. 마이크로소프트웨어 2006/09 S/W로 여는 세상 - 관점지향의 개념잡기 -상황중심의 프로그래밍 (임백준) (http://www.zdnet.co.kr/builder/dev/etc/0,39031619,39154322-1,00.htm)
  4. 3번 자료에 대한 반론 - http://toby.epril.com/?p=229 (이일민님의 블로그)
  5. 마이크로소프트웨어 2007/03 Cover Story- OOP한계 극복패러다임 AOP (이일민,김백기,박재성, 류대원)
  6. 마이크로소프트웨어 2007/03 프로그래밍 실전노트 - 클로저(코드 블록)의 개념과 유용성 (서광열)
  7. 마이크로소프트웨어 2006/11 Coverd story1 -효율적인 프레임워크를 위한 프레임워크의 재발견 (이일민)
  8. Head First DesignPatterns - 6장 Command Pattern (에릭 프리먼, 일리자베스 프리먼, 케이시 시에라, 버트베이츠)
  9. 한빛네트워크에 올라온 AOP소개 기사 : http://network.hanb.co.kr/view.php?bi_id=968

History

Last edited on 10/15/2008 18:43 by benelog

Comments (0)

You must log in to leave a comment. Please sign in.