代理分爲靜態代理和動態代理。java
package effectiveJava.proxy; public interface HelloService { void sayHello(); }
2,代理元git
package effectiveJava.proxy; public class HelloServiceImpl implements HelloService{ @Override public void sayHello() { System.out.println("Hello Proxy."); } }
3,代理類github
package effectiveJava.proxy.staticProxy; import effectiveJava.proxy.HelloService; public class LogProxy implements HelloService { private HelloService service; public LogProxy(HelloService service) { this.service = service; } @Override public void sayHello() { System.out.println("Static Proxy : Before Hello...."); service.sayHello(); System.out.println("Static Proxy : After Hello...."); } }
4,測試類ide
package effectiveJava.proxy.staticProxy; import effectiveJava.proxy.HelloServiceImpl; public class LogProxyDemo { public static void main(String[] args) { LogProxy logProxy = new LogProxy(new HelloServiceImpl()); logProxy.sayHello(); } }
5,測試結果函數
Static Proxy : Before Hello....
Hello Proxy.
Static Proxy : After Hello....
動態代理測試
動態代理地實現有兩種方式:1)基於JDK的動態代理;2)基於CGLIB的動態代理;this
1)基於JDK的動態代理編碼
APIspa
public class Proxy implements java.io.Serializable { /** * 建立代理實例 * @param loader 代理元的類加載器 * @param interfaces 代理元的接口 * h 一個 InvocationHandler 對象 */ public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h); }
/** * * 每一個代理的實例都有一個與之關聯的 InvocationHandler 實現類, * 若是代理的方法被調用,那麼代理便會通知和轉發給內部的 InvocationHandler 實現類,由它決定處理。 */ public interface InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable; }
編碼實現代理
package effectiveJava.proxy.v0; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class HelloInvocation implements InvocationHandler { /** * 代理元 */ private Object target; public HelloInvocation(Object target) { this.target = target; } /** * * @param proxy 代理類實例 * @param method 實際要調用的方法 * @param args 實際要調用方法的參數類型 * @return 結果值 * @throws Throwable */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("HelloInvocation : Before Hello...."); Object reslut = method.invoke(target, args); System.out.println("HelloInvocation : After Hello...."); return reslut; } }
3,測試類
package effectiveJava.proxy.v0; import effectiveJava.proxy.HelloService; import effectiveJava.proxy.HelloServiceImpl; import java.lang.reflect.Proxy; /** * 經過Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)建立代理對象的實例 */ public class HelloInvocationDemo { public static void main(String[] args) { HelloServiceImpl helloService = new HelloServiceImpl(); HelloInvocation helloInvocation = new HelloInvocation(helloService); HelloService impl = (HelloService)Proxy.newProxyInstance( helloService.getClass().getClassLoader(), helloService.getClass().getInterfaces(), helloInvocation); impl.sayHello(); } }
4,測試結果
HelloInvocation : Before Hello....
Hello Proxy.
HelloInvocation : After Hello....
2)基於CGLIB的動態代理
Cglib是基於繼承的方式進行代理,代理類去繼承目標類,每次調用代理類的方法都會被方法攔截器攔截,在攔截器中才是調用目標類的該方法的邏輯。所以,基於CGLIB的動態代理不須要接口。
編碼實現
1,引入架包
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.2.2</version> </dependency>
package effectiveJava.proxy.cglib; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class LogInterceptor implements MethodInterceptor { @Override public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { System.out.println("Cglib : Before hello..."); //調用父委方法 Object result = methodProxy.invokeSuper(object, args); System.out.println("Cglib : After hello..."); return result; } }
4,測試類
package effectiveJava.proxy.cglib; import effectiveJava.proxy.HelloService; import effectiveJava.proxy.HelloServiceImpl; import net.sf.cglib.proxy.Enhancer; public class CglibDemo { public static void main(String[] args) { //建立Enhancer對象,相似於JDK動態代理的Proxy類 Enhancer enhancer = new Enhancer(); //設置父類 enhancer.setSuperclass(HelloServiceImpl.class); //設置回調函數(攔截器) enhancer.setCallback(new LogInterceptor()); //建立代理類實例 HelloService service = (HelloService)enhancer.create(); service.sayHello(); } }
5,測試結果
Cglib : Before hello...
Hello Proxy.
Cglib : After hello...