浏览 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; }
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |