Spring JDK動態(tài)代理實現(xiàn)過程詳解
這篇文章主要介紹了Spring JDK動態(tài)代理實現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
1. 創(chuàng)建項目
在 MyEclipse 中創(chuàng)建一個名稱為 springDemo03 的 Web 項目,將 Spring 支持和依賴的 JAR 包復制到 Web 項目的 WEB-INF/lib 目錄中,并發(fā)布到類路徑下。
2. 創(chuàng)建接口 CustomerDao
在項目的 src 目錄下創(chuàng)建一個名為 com.mengma.dao 的包,在該包下創(chuàng)建一個 CustomerDao 接口,編輯后如下所示。
package com.mengma.dao;
public interface CustomerDao {
public void add(); // 添加
public void update(); // 修改
public void delete(); // 刪除
public void find(); // 查詢
}
3. 創(chuàng)建實現(xiàn)類 CustomerDaoImpl
在 com.mengma.dao 包下創(chuàng)建 CustomerDao 接口的實現(xiàn)類 CustomerDaoImpl,并實現(xiàn)該接口中的所有方法,如下所示。
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. 創(chuàng)建切面類 MyAspect
在 src 目錄下,創(chuàng)建一個名為 com.mengma.jdk 的包,在該包下創(chuàng)建一個切面類 MyAspect,編輯后如下所示。
package com.mengma.jdk;
public class MyAspect {
public void myBefore() {
System.out.println("方法執(zhí)行之前");
}
public void myAfter() {
System.out.println("方法執(zhí)行之后");
}
}
上述代碼中,在切面中定義了兩個增強的方法,分別為 myBefore() 方法和 myAfter() 方法,用于對目標類(CustomerDaoImpl)進行增強。
5. 創(chuàng)建代理類 MyBeanFactory
在 com.mengma.jdk 包下創(chuàng)建一個名為 MyBeanFactory 的類,在該類中使用 java.lang.reflect.Proxy 實現(xiàn) JDK 動態(tài)代理,如下所示。
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();
// 創(chuàng)建切面類實例
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;
}
});
}
}
上述代碼中,定義了一個靜態(tài)的 getBean() 方法,這里模擬 Spring 框架的 IoC 思想,通過調用 getBean() 方法創(chuàng)建實例,第 14 行代碼創(chuàng)建了 customerDao 實例。
第 16 行代碼創(chuàng)建的切面類實例用于調用切面類中相應的方法;第 18~26 行就是使用代理類對創(chuàng)建的實例 customerDao 中的方法進行增強的代碼,其中 Proxy 的 newProxyInstance() 方法的第一個參數是當前類的類加載器,第二參數是所創(chuàng)建實例的實現(xiàn)類的接口,第三個參數就是需要增強的方法。
在目標類方法執(zhí)行的前后,分別執(zhí)行切面類中的 myBefore() 方法和 myAfter() 方法。
6. 創(chuàng)建測試類 JDKProxyTest
在 com.mengma.jdk 包下創(chuàng)建一個名為 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();
// 執(zhí)行方法
customerDao.add();
customerDao.update();
customerDao.delete();
customerDao.find();
}
}
上述代碼中,在調用 getBean() 方法時,獲取的是 CustomerDao 類的代理對象,然后調用了該對象中的方法。
7. 運行項目并查看結果
使用 JUnit 測試運行 test() 方法,運行成功后,控制臺的輸出結果如圖 1 所示。
從下圖的輸出結果中可以看出,在調用目標類的方法前后,成功調用了增強的代碼,由此說明,JDK 動態(tài)代理已經實現(xiàn)。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Java中實現(xiàn)高清圖片壓縮的兩種方案(最新推薦)
文章首先介紹了Java中進行高清圖片壓縮的基本方法,包括使用Java標準庫ImageIO和第三方庫ApacheCommonsCompress,通過示例代碼展示了如何調整圖像質量和使用第三方工具來壓縮圖片文件,感興趣的朋友跟隨小編一起看看吧2025-01-01
解決?IDEA?Maven?項目中"Could?not?find?artifact"?
這篇文章主要介紹了解決IDEA Maven項目中Could not?find?artifact問題的常見情況和解決方案,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-07-07

