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 所示。

從圖 1 的輸出結果中可以看出,在調用目標類的方法前后,成功調用了增強的代碼,由此說明,JDK 動態代理已經實現。

 

 


圖 1  運行結果


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM