spring 兩大思想,其一是IOC,其二就是AOP..而AOP的原理就是java 的動態代理機制。這里主要記錄java 動態代理的實現及相關類的說明。
java 動態代理機制依賴於InvocationHandler接口、Proxy類。這是java 實現動態代理必須用到的。
一、InvocationHandler:該接口中只有一個方法 public Object invoke(Object proxy, Method method, Object[] args)throws Throwable;
該方法的作用目標對象的方法會轉發由InvocationHandle這個接口的invoke方法來調用
/** * invoke 是 InvocationHandler 接口的唯一方法 * 當我們使用動態代理調用目標對象的方法時,
* 目標對象的方法會轉發由InvocationHandle這個接口的invoke方法來調用 * 參數 1、proxy ==> 代理的目標對象 * 2、method ==> 目標對象要調用的方法 * 3、args ==> 目標對象要調用的方法的參數數據 * */
以下是源碼對invoke方法的解釋
/** * Processes a method invocation on a proxy instance and returns * the result. This method will be invoked on an invocation handler * when a method is invoked on a proxy instance that it is * associated with. */
二、Proxy:Proxy類的作用及時動態創建一個代理對象的類,Proxy提供了許多方式,用了最多的是newProxyInstance
/** * * @param target * @return * * Proxy.newProxyInstance(loader, interfaces, h) 說明: * Proxy類的作用及時動態創建一個代理對象的類,Proxy提供了許多方式,用了最多的是newProxyInstance * 參數 1、loader ==> 一個ClassLoader對象,定義了由哪個ClassLoader對象來對生成的代理對象進行加載 * 2、interfaces ==> 一個Interface對象的數組,表示的是我將要給我需要代理的對象提供一組什么接口, * 如果我提供了一組接口給它,那么這個代理對象就宣稱實現了該接口(多態),這樣我就能調用這組接口中的方法了 * 3、h ==> 一個InvocationHandler對象,表示的是當我這個動態代理對象在調用方法的時候, * 會關聯到哪一個InvocationHandler對象上 * * */
以下是源碼的解釋
/** * Returns an instance of a proxy class for the specified interfaces * that dispatches method invocations to the specified invocation * handler. */
三、動態代理的實現
1、創建布標對象的接口Hello.java
/** * java proxy InvocationHandler 動態代理公共接口 * * @author dyf * */ public interface Hello { void sayHello(); void run(String name,int count); }
2、創建代理類DynaProxy.java
package cn.dyf.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * java proxy InvocationHandler 實現公共接口代理對象 * 動待代理對象需實現InvocationHandler接口,重新invoke方法 * @author dyf * */ public class DynaProxy implements InvocationHandler{ private Object target; /** * * @param target * @return * * Proxy.newProxyInstance(loader, interfaces, h) 說明: * Proxy類的作用及時動態創建一個代理對象的類,Proxy提供了許多方式,用了最多的是newProxyInstance * 參數 1、loader ==> 一個ClassLoader對象,定義了由哪個ClassLoader對象來對生成的代理對象進行加載 * 2、interfaces ==> 一個Interface對象的數組,表示的是我將要給我需要代理的對象提供一組什么接口, * 如果我提供了一組接口給它,那么這個代理對象就宣稱實現了該接口(多態),這樣我就能調用這組接口中的方法了 * 3、h ==> 一個InvocationHandler對象,表示的是當我這個動態代理對象在調用方法的時候, * 會關聯到哪一個InvocationHandler對象上 * * */ public Object bind(Object target) { this.target = target; return Proxy.newProxyInstance(this.target.getClass().getClassLoader(), this.target.getClass().getInterfaces(), this); } /** * invoke 是 InvocationHandler 接口的唯一方法 * 當我們使用動態代理調用目標對象的方法時,目標對象的方法會轉發由InvocationHandle這個接口的invoke方法來調用 * 參數 1、proxy ==> 代理的目標對象 * 2、method ==> 目標對象要調用的方法 * 3、args ==> 目標對象要調用的方法的參數數據 * */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; result = method.invoke(this.target, args); return result; } }
3、創建App測試類
package cn.dyf.proxy; public class ProxyApp { public static void main(String[] args) { // new StaticProxy(new SjHello()).sayHello(); Hello bind = (Hello)new DynaProxy().bind(new SjHello()); bind.sayHello(); bind.run("小明", 100); } }
