代理模式:對一個對象提供另一個對象,能夠在調用正式對象前進行操做,在以後也能夠進行操做。ide
1:靜態代理this
public interface Shopping { void shop(); }
public class ShoppingImpl implements Shopping { @Override public void shop() { System.out.println("我要去買東西!"); } }
public class ShoppingProxy implements Shopping { private Shopping shopping; public ShoppingProxy(Shopping shopping) { this.shopping = shopping; } @Override public void shop() { System.out.println("準備錢"); shopping.shop(); System.out.println("付帳走"); } }
public class ProxyTest { public static void main(String[] args) { Shopping shopping = new ShoppingImpl(); Shopping shopping1 = new ShoppingProxy(shopping); shopping1.shop(); } }
靜態代理spa
優勢:在不修改原類的基礎上,能夠進行功能的修改。代理
缺點:當我建立一個方法的時候,就須要手動的修改代理類。code
2:動態代理對象
public class DynamicProxy implements InvocationHandler { private Shopping shopping; public DynamicProxy(Shopping shopping) { this.shopping = shopping; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("準備錢"); Object result = method.invoke(shopping,args); System.out.println("付帳走"); return result; } public Object newProxyInstance(){ return Proxy.newProxyInstance(shopping.getClass().getClassLoader(), shopping.getClass().getInterfaces(),this); } }
public class ProxyTest { public static void main(String[] args) { Shopping shopping = new ShoppingImpl(); DynamicProxy dynamicProxy = new DynamicProxy(shopping); shopping = (Shopping)dynamicProxy.newProxyInstance(); shopping.shop(); } }
Proxy.newProxyInstance的三個參數blog
ClassLoader loader, //制定類的加載器
Class<?>[] interfaces, //制定目標實現的接口
InvocationHandler h //動態處理器,執行目標方法時,會觸發動態處理器
雖然動態代理減小了靜態代理工做量,可是惟一的缺點就是必須依賴接口。
3:CJLIB動態代理
接口
public class CglibProxy implements MethodInterceptor { private Object target; public Object getInstance(final Object target) {
this.target = target;
Enhancer enhancer = new Enhancer();
//設置enhancer的父類
enhancer.setSuperclass(this.target.getClass());
//設置enhancer的回調對象
enhancer.setCallback(this);
//建立代理對象
return enhancer.create();
}
/** * o:cglib生成的代理對象 * method:被代理對象方法 * objects:方法入參 * methodProxy: 代理方法 */ @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("準備錢"); Object result = methodProxy.invokeSuper(o,objects); System.out.println("付帳走"); return result; } }
public class ProxyTest { public static void main(String[] args) { Shopping shopping = new ShoppingImpl(); CglibProxy cglibProxy = new CglibProxy(); ShoppingImpl shopping1 = (ShoppingImpl)cglibProxy.getInstance(shopping); shopping1.shop(); } }
cglib主要是針對類的代理,生成一個子類,覆蓋全部的方法,可是final是不能被代理的get