一、如何理解代理技術
Proxy:不用你去做,別人代替你去處理。如Windows快捷方式,又如房屋中介
起到一個中介作用,通過代理對象,可以去掉客戶不能看到的內容和服務或者添加客戶需要的額外服務。
二、代理模式
代理模式使用代理對象完成用戶請求,屏蔽用戶對真實對象的訪問。現實世界的代理人被授權執行當事人的一些事宜,無需當事人出面,從第三方的角度看,似乎當事人並不存在,因為他只和代理人通信。
而事實上代理人是要有當事人的授權,並且在核心問題上還需要請示當事人。
在軟件設計中,使用代理模式的意圖也很多,比如因為安全原因需要屏蔽客戶端直接訪問真實對象,或者在遠程調用中需要使用代理類處理遠程方法調用的技術細節 (如 RMI),
也可能為了提升系統性能,對真實對象進行封裝,從而達到延遲加載的目的。
代理模式角色分為 4 種:
1.主題接口:定義代理類和真實主題的公共對外方法,也是代理類代理真實主題的方法;
2.真實主題:真正實現業務邏輯的類;
3.代理類:用來代理和封裝真實主題;
4.Main:客戶端,使用代理類和主題接口完成一些工作。
三、具體使用
1.靜態代理
/** * Created by solverpeng on 2016/6/29. */ public interface Factory { void say(); void produce(); } Factory /** * NikeFatory * * @author solverpeng * @create 2016-06-29-11:28 */ public class NikeFactory implements Factory { @Override public void say() { System.out.println("我要開始生產了!"); } @Override public void produce() { System.out.println("正在生產Nike衣服!"); } } NikeFactory /** * NikeFactoryProxy * * @author solverpeng * @create 2016-06-29-11:30 */ public class NikeFactoryProxy implements Factory { private NikeFactory nikeFactory; public NikeFactoryProxy() { this.nikeFactory = new NikeFactory(); } @Override public void say() { before(); nikeFactory.say(); after(); } @Override public void produce() { before(); nikeFactory.produce(); after(); } private void after() { System.out.println("大家做的不錯!"); } private void before() { System.out.println("在正式開始生產之前,我要說兩句!"); } } NikeFactoryProxy @Test public void testStaticProxy() { NikeFactoryProxy nikeFactoryProxy = new NikeFactoryProxy(); nikeFactoryProxy.say(); nikeFactoryProxy.produce(); } testStaticProxy2.JDK動態代理
@Test public void testJDKProxy() { Factory proxyInstance = (Factory) Proxy.newProxyInstance(NikeFactory.class.getClassLoader(), NikeFactory.class.getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(NikeFactory.class.newInstance(), args); } }); proxyInstance.say(); proxyInstance.produce(); } testJDKProxy /** * 通用的代理生產工廠 * * @author solverpeng * @create 2016-06-29-11:45 */ public class DynamicProxy implements InvocationHandler { private Object target; public DynamicProxy(Object target) { this.target = target; } @SuppressWarnings("unchecked") public <T> T getProxy() { return (T)Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(target, args); } } DynamicProxy @Test public void testJDKProxy2() { DynamicProxy dynamicProxy = new DynamicProxy(new NikeFactory()); Factory proxy = dynamicProxy.getProxy(); proxy.say(); proxy.produce(); } testJDKProxy23.CGLIB動態代理(需要額外導入cglib包)
/** * CglibProxy * * @author solverpeng * @create 2016-06-29-14:40 */ public class CglibProxy implements MethodInterceptor{ private static CglibProxy instance = new CglibProxy(); public CglibProxy() { } public static CglibProxy getInstance() { return instance; } @SuppressWarnings("unchecked") public <T> T getProxy(Class<T> cls) { return (T)Enhancer.create(cls, this); } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { return methodProxy.invokeSuper(o, objects); } } CglibProxy @Test public void testCglibProxy2() { NikeFactory proxy = CglibProxy.getInstance().getProxy(NikeFactory.class); proxy.say(); proxy.produce(); } testCglibProxy2