1. 程式人生 > 其它 >六、springMVC資料轉換&格式化&校驗&錯誤訊息顯示和國際化

六、springMVC資料轉換&格式化&校驗&錯誤訊息顯示和國際化

動態代理可以為任何類做代理且是在執行時生成,通過呼叫JDK提供的一個代理工廠Proxy.newProxyInstance來生成代理,這個代理工廠需要配置三個引數:

1.生成的代理類的二進位制位元組碼的載入器以生成代理類的Class例項去例項化代理類以最終被返回呼叫

2.被代理的介面

3.代理邏輯,此代理邏輯以InvocationHandler的形式通過已生成的代理類Class例項反射呼叫此代理類的構造器注入到代理例項 它有對目標類的引用,它有裝配代理邏輯的通用介面invoke,這個invoke最關鍵知道代理目標Method,代理類中的方法只需呼叫這個invoke就好了,ProxyGenerator負責Method分配到各個代理類中的方法。

 

代理類位元組碼生成邏輯:

根據傳進來的介面能做一下事情:

1.class 代理類 extends Proxy implements 要代理的介面 { //繼承Proxy能構造器注入InvocationHandler

2.public 代理類(InvocationHandler h) {

   super(h);

3.private static Method 要代理的介面中的方法的Method物件;

4.static {

  要代理的介面中的方法的Method物件=Class.forName("要代理的介面的名字")

                           .getMethod("要代理的介面中的方法的名字",new Class[]{Class.forName}

5.public final 返回型別 要代理的介面中的方法(引數) {

    return (返回型別)this.h.invoke(this,要代理的介面中的方法的Method物件,引數);

 

介面類

package com.life.proxy;

public interface IUserDao {
    public void save();
}

目標物件

package com.life.proxy;

public class UserDao implements IUserDao{

    @Override
    public void save() {
        System.out.println(
"儲存資料"); } }

代理工廠

package com.life.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyFactory {

    private Object target;// 維護一個目標物件

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

    // 為目標物件生成代理物件
    public Object getProxyInstance() {
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
                new InvocationHandler() {

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

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

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

測試類

package com.life.proxy;

import org.junit.Test;

public class TestProxy {

    @Test
    public void testDynamicProxy (){
        IUserDao target = new UserDao();
        System.out.println(target.getClass());  //輸出目標物件資訊
        IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();
        System.out.println(proxy.getClass());  //輸出代理物件資訊
        proxy.save();  //執行代理方法
    }
}