1. 程式人生 > >經典三層框架初識(二)---Spring 3.3Cglib代理

經典三層框架初識(二)---Spring 3.3Cglib代理

JDK的動態代理機制只能代理實現了介面的類,而不能實現介面的類就不能實現JDK的動態代理,cglib是針對類來實現代理的,他的原理是對指定的目標類生成一個子類,並覆蓋其中方法實現增強,但因為採用的是繼承,所以不能對final修飾的類進行代理。 

Cglib代理,也叫作子類代理,它是在記憶體中構建一個子類物件從而實現對目標物件功能的擴充套件

Cglib子類代理實現方法: 1.需要引入cglib的jar檔案,但是Spring的核心包中已經包括了Cglib功能,所以直接引入Spring-core.jar即可. 2.引入功能包後,就可以在記憶體中動態構建子類 3.代理的類不能為final,否則報錯 4.目標物件的方法如果為final/static,那麼就不會被攔截,即不會執行目標物件額外的業務方法.

程式碼演示如下:

/**
 * 目標物件,沒有實現任何介面
 */
public class UserDao {

    public void save() {
        System.out.println("----儲存資料成功!----");
    }
}

Cglib代理工廠:ProxyFactory

/**
 * Cglib子類代理工廠
 * 對UserDao在記憶體中動態構建一個子類物件
 */
public class ProxyFactory implements MethodInterceptor{
    //維護目標物件
    private Object target;

    public ProxyFactory(Object target) {
        this.target = target;
    }

    //給目標物件建立一個代理物件
    public Object getProxyInstance(){
        //1.工具類
        Enhancer en = new Enhancer();
        //2.設定父類
        en.setSuperclass(target.getClass());
        //3.設定回撥函式
        en.setCallback(this);
        //4.建立子類(代理物件)
        return en.create();

    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("開始事務...");

        //執行目標物件的方法
        Object returnValue = method.invoke(target, args);

        System.out.println("提交事務...");

        return returnValue;
    }
}

 測試類APPTest:

/**
 * 測試類
 */
public class AppTest {

    @Test
    public void test(){
        //目標物件
        UserDao target = new UserDao();

        //代理物件
        UserDao proxy = (UserDao)new ProxyFactory(target).getProxyInstance();

        //執行代理物件的方法
        proxy.save();
    }
}