標籤:
1.介面
public interface Hello { public void sayHello();}
2.執行個體類
public class Hello2 { public void sayHello() { System.out.println("hello world2!"); }}
public class Hello3 extends Hello2{ }
public class HelloImpl implements Hello{ @Override public void sayHello() { System.out.println("hello world!"); }}
3.JDK動態代理
ublic class JdkTest implements InvocationHandler{ private Object object; @SuppressWarnings("unchecked") public <T> T bind(Object obj){ this.object = obj; return (T)Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before sayHello"); method.invoke(object, null); System.out.println("after sayHello"); return null; } public static void main(String[] args) { JdkTest test = new JdkTest(); Hello hello = test.bind(new HelloImpl()); hello.sayHello(); }}
4.cglib動態代理
public class CglibTest implements MethodInterceptor{ private Object obj; /** * 普通介面類代理 * @author tomsnail * @date 2015年4月2日 上午10:36:10 */ public <T> T instance(T obj){ this.obj = obj; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.obj.getClass()); enhancer.setCallback(this); return (T)enhancer.create(); } @Override public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { System.out.println("before sayHello"); arg3.invoke(obj, arg2); System.out.println("after sayHello"); return null; } /** * 無介面類代理 * @author tomsnail * @date 2015年4月2日 上午10:35:58 */ public <T> T instanceObject(T obj){ T t = (T)Enhancer.create(obj.getClass(),new MethodInterceptor(){ @Override public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { System.out.println("hello2 proxy"); return arg3.invokeSuper(arg0, arg2); } }); return t; } /** * 無介面類代理 * @author tomsnail * @date 2015年4月2日 上午10:35:58 */ public <T> T instanceSuperObject(T obj){ T t = (T)Enhancer.create(obj.getClass(),NoOp.INSTANCE);//無任何代理時,調用父類方法實現 return t; } public static void main(String[] args) { CglibTest test = new CglibTest(); Hello hello = test.instance(new HelloImpl()); hello.sayHello(); Hello2 hello2 = test.instanceObject(new Hello2());//無介面類的動態代理 hello2.sayHello(); Hello2 hello3 = test.instanceSuperObject(new Hello3());//子類沒有重寫父類方法的動態代理 hello3.sayHello(); }}
5.小小總結一下
JDK的動態代理只能通過介面進行處理,如果沒有介面的,會很難處理。cglib沒有這一限制。
還有就是效能,我看見一篇網上已經有了對比,在jdk7/8與cglib相比,反而jdk的效能很好,見http://www.cnblogs.com/haiq/p/4304615.html
重學JAVA基礎(三):動態代理