我们来做个最简单的代理工厂,用于把对象给代理了。代码很简洁,就是一个类,用于返回封装的对象。
使用起来尤其的简单。具体的说明我就不用写了,大家看下最下面的输出日志就会明白了。
代理工厂的代码如下。
package net.chinacsharp.jdf.proxy.proxyfactory; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * 传统的代理工厂 * @author keyboardsun * */ public class ProxyFactory implements InvocationHandler{ private static transient Log log = LogFactory.getLog( ProxyFactory.class ); private Object obj = null;// 这里封装的对象 public ProxyFactory( Object o ){ obj = o; log.debug( "代理了一个类噢:" + o.getClass().getName() ); } /** * 代理的方法都经过这里调用 * @param arg0 * @param m * @param parms * @return * @throws Throwable */ public Object invoke( Object arg0, Method m, Object[] parms ) throws Throwable{ log.debug("调用对象:"+obj.getClass().getName()) ; log.debug("调用方法:"+m.getName()) ; if(parms!=null){ for( int i = 0; i < parms.length; i++ ){ log.debug("调用参数:"+parms[i]==null?"":parms[i].toString()) ; } } Object returnResult = m.invoke( obj, parms ); return returnResult; } public static Object newInstance( Object o ){ InvocationHandler handler = new ProxyFactory( o ); ClassLoader cl = o.getClass().getClassLoader(); Class c = null; //因为这里代理只能用接口 if( o.getClass().isInterface() ){ c = o.getClass(); }else{ Class[] interfaces = o.getClass().getInterfaces(); if( interfaces != null && interfaces.length > 0 ){ c = interfaces[0]; } } return Proxy.newProxyInstance( cl, new Class[] {c}, handler ); } }
下面我们新建一个接口,然后实现这个接口。
接口类 ITest 接口,代码如下
import java.util.HashMap; public interface ITest{ public void test2(HashMap m,String s,long f); }
接口实现类的 Test.java 代码如下
import java.util.HashMap; public class Test implements ITest{ public void test2( HashMap m, String s, long f ){ System.out.println("成功调用到test2方法"); } }
下面我们运行main函数
public static void main(String args[]) Exception{ HashMap map = new HashMap(); map.put("Testkey","TestValue"); ITest test = (ITest) ProxyFactory.newInstance(Test.class.newInstance()); test.test2(map,"good luck",2009); }
下面是输出参数,明白了吧,呵呵。
[2009-07-27 12:44:52,765] [main] (ProxyFactory.java:22) DEBUG net.chinacsharp.jdf.proxy.proxyfactory.ProxyFactory - 代理了一个类噢:net.jkf.mysql.Test [2009-07-27 12:44:52,781] [main] (ProxyFactory.java:34) DEBUG net.chinacsharp.jdf.proxy.proxyfactory.ProxyFactory - 调用对象:net.jkf.mysql.Test [2009-07-27 12:44:52,781] [main] (ProxyFactory.java:35) DEBUG net.chinacsharp.jdf.proxy.proxyfactory.ProxyFactory - 调用方法:test2 [2009-07-27 12:44:52,781] [main] (ProxyFactory.java:38) DEBUG net.chinacsharp.jdf.proxy.proxyfactory.ProxyFactory - 调用参数:{Testkey=TestValue} [2009-07-27 12:44:52,781] [main] (ProxyFactory.java:38) DEBUG net.chinacsharp.jdf.proxy.proxyfactory.ProxyFactory - 调用参数:good luck [2009-07-27 12:44:52,781] [main] (ProxyFactory.java:38) DEBUG net.chinacsharp.jdf.proxy.proxyfactory.ProxyFactory - 调用参数:2009 成功调用到test2方法
这里的代理工厂可以直接拿过去就可以用,很简单吧。
这里在代理工厂的invoke方法里面加上invokeBefore 和 invokeAfter用于控制事务,统计方法调用时间等等信息。
作者:keyboardsun 转载请标明出处