創建一個普通的接口java
package com.tester.cls.design.mode; public interface IUser { public String getName(); public void setName(String name); public void setUser(int id,String name); public int getId(); public void setId(int id); }
構建一個實現類(簡單的javaBean)ide
package com.tester.cls.design.mode; public class User implements IUser{ private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void setUser(int id,String name) { setId(id); setName(name); } @Override public String toString() { return super.toString(); } }
實現代理測試
InvocationHandler實質是攔截器,用來攔截動態代理的方法調用。this
Proxy纔是動態代理,攔截器攔截Proxy生成的代理對象的方法spa
package com.tester.cls.design.mode; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ObjectProxy implements InvocationHandler{ IUser delegateTarget = null; public IUser delegate(IUser delegateTarget) { this.delegateTarget = delegateTarget; return (IUser) Proxy.newProxyInstance(ObjectProxy.class.getClassLoader(), delegateTarget.getClass().getInterfaces(),this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println(method.getName()+"-"+method.getReturnType()); return method.invoke(delegateTarget, args); } }
測試,測試一下代理
public static void main(String[] args) { User u = new User(); ObjectProxy objHandler = new ObjectProxy(); IUser delegate = objHandler.delegate(u); //注意,返回值的類型是註解類型 delegate.setUser(2014, "zhangsan"); System.out.println(delegate.getId()+"-"+delegate.getName()); System.out.println(u.getId()+"-"+u.getName()); u.setUser(2048, "張三"); System.out.println(delegate.getId()+"-"+delegate.getName()); System.out.println(u.getId()+"-"+u.getName()); }
輸出結果code
2014-zhangsan 2014-zhangsan 2048-張三 2048-張三
Cglib實現動態代理,Cglib的效率高於JDK動態代理,由於Cglib是有底層字節碼方式生產一個代理類的(此觀點來自於互聯網,本人水平有限,目前只將概念)。對象
cglib使用底層ASM實現動態類的繼承(很牛逼吧,咱們平常使用的類是靜態繼承的,這簡直是逆天的趕腳啊~~),能力好的童鞋建議去看源碼。繼承
(注:此處不提供 cglib.jar下載)接口
public class CglibProxy implements MethodInterceptor{ private Enhancer enhancer = new Enhancer(); public Object getProxy(Class clazz){ //設置須要建立子類的類 enhancer.setSuperclass(clazz); enhancer.setCallback(this); //經過字節碼技術動態建立子類實例 return enhancer.create(); } //實現MethodInterceptor接口方法 public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("前置代理"); //經過代理類調用父類中的方法 Object result = proxy.invokeSuper(obj, args); System.out.println("後置代理"); return result; } }
測試以下,但不提供結果
public class DoCGLib { public static void main(String[] args) { CglibProxy proxy = new CglibProxy(); //經過生成子類的方式建立代理類 SayHello proxyImp = (SayHello)proxy.getProxy(SayHello.class); proxyImp.say(); } }
好了,這就是動態代理的基本認識
try doing it;