代理模式(Proxy)是經過代理對象訪問目標對象,這樣不直接訪問目標對象的好處是:能夠在目標對象的功能基礎上添加額外的功能,即實現對目標對象功能的擴展。java
靜態代理模式類圖如上所示,Subject接口是程序中的業務邏輯接口,RealSubject類是實現了Subject接口的真正業務類,RealSubjectProxy是實現了Subject接口的代理類,而且以組合的方式封裝了RealSubject類,客戶端使用RealSubject類時並不直接調用RealSubject類,而是經過調用RealSubjectProxy類來使用RealSubject,RealSubjectProxy.operation()方法會調用RealSubject.operation()方法,從而實現對RealSubject.operation()方法的使用。ide
缺點:每個RealSubject類都須要建立本身對應的代理類,當須要建立的代理類不少時,就很麻煩。this
package com.hs.pattern.proxy; public interface Subject { public void operation(); }
package com.hs.pattern.proxy; public class RealSubject implements Subject { @Override public void operation() { System.out.println("this is RealSubject"); } }
package com.hs.pattern.proxy; public class RealSubjectProxy implements Subject { private Subject subject; public RealSubjectProxy(Subject subject) { this.subject = subject; } @Override public void operation() { System.out.println("前置處理"); subject.operation(); System.out.println("後置處理"); } }
package com.hs.pattern.proxy; public class Client { public static void main(String[] args) { RealSubject realSubject = new RealSubject(); RealSubjectProxy realSubjectProxy = new RealSubjectProxy(realSubject); realSubjectProxy.operation(); } }
jdk的動態代理須要實現InvocationHandler接口,而且須要用到Proxy.newProxyInstance()方法。spa
缺點:被代理的類必須實現的某個接口,若是該類沒有實現任何接口則沒法使用該方法。代理
package com.hs.pattern.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * jdk的動態代理實現代理模式 * @author Administrator * */ public class SubjectJdkProxy implements InvocationHandler { private Subject subject; public SubjectJdkProxy( Subject subject ){ this.subject = subject; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("前置處理"); Object result = method.invoke(subject, args); System.out.println("後置處理"); return result; } public Object getProxy(){ //建立代理對象 return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), subject.getClass().getInterfaces(), this); } }
package com.hs.pattern.proxy; public class Client { public static void main(String[] args) { RealSubject realSubject = new RealSubject(); SubjectJdkProxy subjectJdkProxy = new SubjectJdkProxy(realSubject); Subject proxy = (Subject)subjectJdkProxy.getProxy(); proxy.operation(); } }
3、Cglib實現代理模式code
上面的靜態代理模式、jdk實現的動態代理模式,被代理的類都必須實現了某個接口,若是某個類只是單純的類,並無實現任何接口,則必須使用Cglib代理實現。Cglib(又稱爲子類代理)他是經過在內存中生成一個子類對象,從而實現對目標對象功能的擴展。對象