论坛首页 Java企业应用论坛

An Industrial-level Dynamic Proxy

浏览 1485 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (4) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-10-30  
/** 
*    
*/ 
package poxy; 

import java.lang.reflect.InvocationHandler; 
import java.lang.reflect.InvocationTargetException; 
import java.lang.reflect.Method; 
import java.lang.reflect.Proxy; 
import java.util.*; 

import callback.PrimitiveUtil; 
/** 
* More industrial-level dynamic proxy , which main detach the Invocation handler and the real instance of a proxy class, 
* which can store many proxy handler with them listener, this is very useful. 
* Mean while, it also can work in multi thread env, so you can use it with Thread pool and Scheduler! 
*    
* @author daniel 
* 
*/ 
public class IndustrialDynamicProxy { 
  /* 
    * container of iface & his InvocationHandler 
    * Note: work in multithread env 
    */ 
  private Map _iface2Handler = new HashMap(); 
    
  /* 
    * Generates the 'caller' side of the caller/listener relationship. 
    */ 
  public Object generateCaller(Class iFace, CallBackType type) { 
    CallBackHanlder newHandler; 
    Object proxy=null; 
    //check iface 
    if(!iFace.isInterface()){ 
        throw new IllegalArgumentException("Class [" + iFace.getName() + "] is not an interface"); 
    } 
    //generate a new handler    
    newHandler = new CallBackHanlder(type); 
    //generate the face's proxy 
    proxy = Proxy.newProxyInstance(iFace.getClassLoader(), 
                    new Class[] { iFace }, 
                    newHandler); 
    //register iface & proxy 
    synchronized(_iface2Handler){ 
      if(_iface2Handler.containsKey(iFace)){ 
        throw new IllegalArgumentException("Caller already generated " + " for interface [" +    
                                                iFace.getName() + "]"); 
      } 
      _iface2Handler.put(iFace, newHandler); 
    } 
    return proxy; 
  } 

  /* 
    * Register a listener for a given interface.    If the caller has not 
         * been registered, then an error will be thrown.    
    */ 
    public void registerListener(Class iFace, Object o) { 
     CallBackHanlder handler; 
        
     if(!iFace.isAssignableFrom(o.getClass())){ 
        throw new IllegalArgumentException("Object [" + o + "] does not " + 
                                         "implement [" + iFace.getName() + 
                                         "]"); 
     } 
        
     synchronized (_iface2Handler) { 
        handler = (CallBackHanlder) _iface2Handler.get(iFace); 
     } 
        
     if(handler == null){ 
        throw new IllegalArgumentException("No callback for interface [" + 
                                         iFace.getName() + "] exists"); 
     } 
        
     handler.addListener(o); 
    } 
  /** 
    * @param args 
    */ 
  public static void main(String[] args) { 
     
    //Base testhandler 
    IndustrialDynamicProxy    x=new IndustrialDynamicProxy(); 
     
    //register iface, get the proxy 
    MyInterface caller = (MyInterface)x.generateCaller(MyInterface.class, CallBackType.RETURN_LAST); 
     
    //register the listener(real instance) 
    x.registerListener(MyInterface.class, new MyInterface(){ 
      @Override 
      public int addTwo(int a, int b) { 
        System.out.println("Target method called"); 
                                return a + b; 
      }        
    }); 
     
    //call the listener 
    int result=caller.addTwo(2, 4); 
    //take a look 
    System.out.println("addTwo(2,4):"+result); 
  } 

  /** 
    * An inner class to operate listeners in private 
    */ 
  static class CallBackHanlder implements InvocationHandler{ 
    /* 
     * container of listeners (real instance) 
     * Note: work in multithread env 
     */ 
    private Set _listeners = new HashSet(); 
    //tool of get right Type 
    private CallBackType _type = null; 
     
    CallBackHanlder(CallBackType type){ 
      this._type=type; 
    } 
     
    private void addListener(Object o){ 
      synchronized(_listeners){ 
        _listeners.add(o); 
      } 
        
    } 
    @Override 
    public Object invoke(Object proxy, Method method, Object[] args) 
        throws Throwable { 
      Set listeners; 
      synchronized (_listeners) { 
                                listeners = new HashSet(_listeners); 
                        } 
      return _type.callListeners(method, args, listeners); 
    } 
     
  } 
} 



//Interface 
interface MyInterface { 
        int addTwo(int a, int b); 
} 

/* 
* CallBackType,    
*/ 
abstract class CallBackType { 
        
        public static final CallBackType RETURN_LAST = new CallBackType() { 
            
                public Object callListeners(Method meth, Object[] methArgs,Set listeners)throws Throwable 
                { 
                        Object last = null; 
                        for (Iterator i=listeners.iterator(); i.hasNext(); ) { 
                                Object listener = (Object)i.next(); 
                         
                                try { 
                                        last = meth.invoke(listener, methArgs); 
                                } catch(InvocationTargetException e) { 
                                        throw e.getTargetException(); 
                                } 
                        } 
                         
                        if (last == null) { 
                                // Nobody listening ... 
                                return PrimitiveUtil.getBasicValue(meth.getReturnType()); 
                        } 

                        return last; 
                } 
        };         
         
        public abstract Object callListeners(Method meth, Object[] methArgs, 
                                                                                 Set listeners) 
                throws Throwable; 
}

 

论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics