'프록시'에 해당되는 글 1건

  1. 2009.06.08 AOP

AOP


AOP는 프레임워크나 아키텍쳐보다는 패러다임에 더 가깝기 때문에 굳이 AOP 전용 언어가 아니더라도 그 의미를 살리는데는 큰 무리가 없다.

이를테면 Javascript의 경우
AOP = {
 addBefore : function(obj, fname, before) {
  var oldFunc = obj[fname];
  obj[fname] = function() {
   before(arguments, obj);
   return oldFunc.apply(this,arguments);
  };
 },

 addAfter : function(obj, fname, after) {
  var oldFunc = obj[fname];
  obj[fname] = function() {
   result = oldFunc.apply(this, arguments);
   try{
    return result;
   } finally{
    after(result, arguments, obj);
   }
  };
 }
};

// example 1
   function setRed(o){
    o.style.color = "red";
   }

   function altBeforeAdvisor(args, targetObject){
    alert("before");
   }
   AOP.addBefore(this, "setRed", altBeforeAdvisor);

   // example 2
   function setBlue(o){
    o.style.color = "blue";
   }

   function altAfterAdvisor(result, args, targetObject){
    alert("after");
   }

   AOP.addAfter(this, "setBlue", altAfterAdvisor);

와 같이 비교적 쉽게 구현할 수 있다.

좀더 나은 예제는

에서 볼수 있다.


자바에서 AOP을 적용 하는 것은 생각보다 쉽지 않다. http://www.voelter.de/data/articles/aop/aop.html 와 같이 AspectJ언어를 사용하지 않는다면 말이다.

스프링처럼 AOP패러다임을 제공하는 프레임워크를 만들기 위해서는 약간의 테크니컬한 기술이 필요하다. 가장 쉽게는 데코레이터 패턴을 생각해 볼 수 있다. 이러 상황에서 상속은 좀 위험하기 때문에 현명한 선택이 아니다.

다소 복잡하지만 Proxy를 사용할 수도 있다.
먼저 Proxy객체는 InvacationHandler를 구현해야 한다.

package com.bleujin.thinlet.sample.invocation;

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


public class NumObjectHandler implements InvocationHandler{
  
  private Object target ;
  NumObjectHandler(Object target){
    this.target = target ;
  }

  public Object invoke(Object proxy, Method m, Object[] argsthrows Throwable {
    System.out.println(m.getName());
    return m.invoke(target, args);
  }
  
}

NumObjectHandler 클래스는 모든 메소드의 호출전에  System.out.println(m.getName());를 실행시켜 준다.


package com.bleujin.thinlet.sample.invocation;

import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

import junit.framework.TestCase;

public class TestInvoke extends TestCase {

  
  public void testSum() throws Exception {
    
    TestInvoke iv = new TestInvoke() ;
    
//    NumObject n3 = new NumObject(3);
//    NumObject n5 = new NumObject(5);
    
    NumObject no3 = new NumObject(3);
    NumObject no5 = new NumObject(5);
    
    INum n3 = (INum)Proxy.newProxyInstance(new SimpleClassLoader(""), no3.getClass().getInterfaces()new NumObjectHandler(no3)) ;
    INum n5 = (INum)Proxy.newProxyInstance(new SimpleClassLoader(""), no5.getClass().getInterfaces()new NumObjectHandler(no5)) ;
    
    iv.add(n3);
    iv.add(n5);
    
    assertEquals(8, iv.sum()) ;
  }
  
  
  private int sum() {
    int result = ;
    for (Object obj : data) {
      result += ((INum)obj).getValue() ;
    }
    return result;
  }


  private List<Object> data = new ArrayList<Object>() 
  private void add(INum numObject) {
    data.add(numObject;
  }
}


'Framework > 아키텍쳐 일반' 카테고리의 다른 글

패키지의 설계 원칙  (0) 2009.06.08
양화 구축  (2) 2009.06.08
Self-Signed Java Applets  (0) 2009.06.01
여섯번째 계 - Encapsulation  (0) 2009.04.14
중복을 볼 수 있는 눈  (0) 2009.03.13
Posted by bleujin