最簡單的是靜態代理方法,即代理模式,這裏就很少囉嗦了。。java
重點說一下JDK的動態代理和Cglib的動態代理吧ide
先說JDK的,須要被代理的類須要有接口,不然沒法實現性能
package proxy.dynamic; public interface IBook { void add(); }
實現接口的類以下
測試
package proxy.dynamic; public class Book implements IBook { @Override public void add() { System.out.println("Add Method!"); } }
建立一個代理類,須要實現一個接口InvocationHandler接口,裏面有一個invoke方法須要實現this
同時建立一個生成實例的方法spa
package proxy.dynamic; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class BookProxy implements InvocationHandler{ private Object target; public Object bind(Object target) { this.target = target; return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);//這裏須要接口 } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result=null; System.out.println("Before"); result=method.invoke(target, args);//執行方法 System.out.println("After"); return result; } }
接下來建立測試類代理
package proxy.dynamic; public class Test { /** * @param args */ public static void main(String[] args) { BookProxy bp = new BookProxy(); IBook book = (IBook) bp.bind(new Book()); book.add(); } }
能夠看到依次輸出了Before,方法,Aftercode
下面說一下Cglib的代理,Cglib代理不須要原類實現接口,依賴Cglib和asm兩個Jar包對象
須要代理的類以下接口
package cglib.proxy; public class Book { public void add() { System.out.println("Add Method!"); } }
建立一個代理類,實現MethodInterceptor接口,同時寫一個生成實例的getInstance方法
package cglib.proxy; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class CglibProxy implements MethodInterceptor{ private Object target; public Object getInstance(Object target){ this.target=target; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.target.getClass()); enhancer.setCallback(this); return enhancer.create(); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("Before"); proxy.invokeSuper(obj, args); System.out.println("After"); return null; } }
接下來就是簡單測試一下
package cglib.proxy; public class Test { /** * @param args */ public static void main(String[] args) { CglibProxy proxy = new CglibProxy(); Book book=(Book) proxy.getInstance(new Book()); book.add(); } }
運行效果同樣的
簡單總結一下,JDK動態代理,須要實現一個接口InvocationHandler,要求被代理的對象必須有一個接口
Cglib代理須要實現MethodInterceptor接口,不須要被代理的類必須有接口
性能方法,參考其餘文章,說JDK代理適合多例模式,而單例模式Cglib更好一些,由於Cglib是用底層的字節碼技術生成實例,耗費時間較長,性能不如JDK動態代理。(有待驗證。。)