Spring JDK動態代理實現過程詳解
這篇文章主要介紹了Spring JDK動態代理實現過程詳解,文中通過示例程式碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
1. 建立專案
在 MyEclipse 中建立一個名稱為 springDemo03 的 Web 專案,將 Spring 支援和依賴的 JAR 包複製到 Web 專案的 WEB-INF/lib 目錄中,併發布到類路徑下。
2. 建立介面 CustomerDao
在專案的 src 目錄下建立一個名為 com.mengma.dao 的包,在該包下建立一個 CustomerDao 介面,編輯後如下所示。
package com.mengma.dao; public interface CustomerDao { public void add(); // 新增 public void update(); // 修改 public void delete(); // 刪除 public void find(); // 查詢 }
3. 建立實現類 CustomerDaoImpl
在 com.mengma.dao 包下建立 CustomerDao 介面的實現類 CustomerDaoImpl,並實現該介面中的所有方法,如下所示。
package com.mengma.dao; public class CustomerDaoImpl implements CustomerDao { @Override public void add() { System.out.println("新增客戶..."); } @Override public void update() { System.out.println("修改客戶..."); } @Override public void delete() { System.out.println("刪除客戶..."); } @Override public void find() { System.out.println("修改客戶..."); } }
4. 建立切面類 MyAspect
在 src 目錄下,建立一個名為 com.mengma.jdk 的包,在該包下建立一個切面類 MyAspect,編輯後如下所示。
package com.mengma.jdk; public class MyAspect { public void myBefore() { System.out.println("方法執行之前"); } public void myAfter() { System.out.println("方法執行之後"); } }
上述程式碼中,在切面中定義了兩個增強的方法,分別為 myBefore() 方法和 myAfter() 方法,用於對目標類(CustomerDaoImpl)進行增強。
5. 建立代理類 MyBeanFactory
在 com.mengma.jdk 包下建立一個名為 MyBeanFactory 的類,在該類中使用 java.lang.reflect.Proxy 實現 JDK 動態代理,如下所示。
package com.mengma.jdk; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import com.mengma.dao.CustomerDao; import com.mengma.dao.CustomerDaoImpl; public class MyBeanFactory { public static CustomerDao getBean() { // 準備目標類 final CustomerDao customerDao = new CustomerDaoImpl(); // 建立切面類例項 final MyAspect myAspect = new MyAspect(); // 使用代理類,進行增強 return (CustomerDao) Proxy.newProxyInstance( MyBeanFactory.class.getClassLoader(),new Class[] { CustomerDao.class },new InvocationHandler() { public Object invoke(Object proxy,Method method,Object[] args) throws Throwable { myAspect.myBefore(); // 前增強 Object obj = method.invoke(customerDao,args); myAspect.myAfter(); // 後增強 return obj; } }); } }
上述程式碼中,定義了一個靜態的 getBean() 方法,這裡模擬 Spring 框架的 IoC 思想,通過呼叫 getBean() 方法建立例項,第 14 行程式碼建立了 customerDao 例項。
第 16 行程式碼建立的切面類例項用於呼叫切面類中相應的方法;第 18~26 行就是使用代理類對建立的例項 customerDao 中的方法進行增強的程式碼,其中 Proxy 的 newProxyInstance() 方法的第一個引數是當前類的類載入器,第二引數是所建立例項的實現類的介面,第三個引數就是需要增強的方法。
在目標類方法執行的前後,分別執行切面類中的 myBefore() 方法和 myAfter() 方法。
6. 建立測試類 JDKProxyTest
在 com.mengma.jdk 包下建立一個名為 JDKProxyTest 的測試類,如下所示。
package com.mengma.jdk; import org.junit.Test; import com.mengma.dao.CustomerDao; public class JDKProxyTest { @Test public void test() { // 從工廠獲得指定的內容(相當於spring獲得,但此內容時代理物件) CustomerDao customerDao = MyBeanFactory.getBean(); // 執行方法 customerDao.add(); customerDao.update(); customerDao.delete(); customerDao.find(); } }
上述程式碼中,在呼叫 getBean() 方法時,獲取的是 CustomerDao 類的代理物件,然後呼叫了該物件中的方法。
7. 執行專案並檢視結果
使用 JUnit 測試執行 test() 方法,執行成功後,控制檯的輸出結果如圖 1 所示。
從下圖的輸出結果中可以看出,在呼叫目標類的方法前後,成功呼叫了增強的程式碼,由此說明,JDK 動態代理已經實現。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。