天天看點

Spring——JDK動态代理

動态代理

靜态代理會為每一個業務增強都提供一個代理類, 由代理類來建立代理對象, 而動态代理并不存在代理類, 代理對象直接由代理生成工具動态生成.

JDK動态代理

  • JDK動态代理是使用 java.lang.reflect 包下的代理類來實作. JDK動态代理動态代理必須要有接口.
  • JDK動态代理是利用反射機制生成一個實作代理接口的匿名類,在調用具體方法前調用InvokeHandler來處理,需要指定一個類加載器,然後生成的代理對象實作類的接口或類的類型,接着處理額外功能.
  • JDK動态代理制能對實作了接口的類生成代理,而不是針對類
//定義兩個dao接口
public interface DeptDao {
    public int addDept();
    public int updateDept();
}


//實作dao接口中的兩個方法
public class DeptDaoImpl  implements DeptDao{
    public int addDept() {
        System.out.println("添加部門到資料庫中");
        return 0;
    }

    public int updateDept() {
        System.out.println("更新部門資訊");
        return 0;
    }
}

           

實作代理

//jdk動态代理:代理類實作一個接口
public class DyProxy<T> implements InvocationHandler {

    public DyProxy() {
    }

    public DyProxy(T target) {
        this.target = target;
    }

    //聲明屬性:接收所代理的對象
    private T target;

    public T getTarget() {
        return target;
    }

    public void setTarget(T target) {
        this.target = target;
    }


    //執行invoke方法就是執行所代理對象的方法
    //proxy:所代理的對象
    //method:所要執行的方法
    //args:要執行方法的參數
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //動态代理對象執行的所代理對象的方法
        //聲明變量來存放執行代理對象方法的傳回值

        Object o=null;
        System.out.println("動态代理開始執行……");

        try {
            o=method.invoke(target, args);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            System.out.println("動态代理對象執行方法時發成異常");
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
            System.out.println("動态代理對象執行方法時發成異常");
        } catch (InvocationTargetException e) {
            e.printStackTrace();
            System.out.println("動态代理對象執行方法時發成異常");
        } finally {
            System.out.println("動态代理執行結束!");
        }


        return o;
    }
}
           

測試

public class TestProxy {
    public static void main(String[] args) {
        //建立代理對象
        UserDaoProxy userDaoProxy=new UserDaoProxy();
        //聲明一個實作類
        DeptDaoImpl ddi=new DeptDaoImpl();
        //使用代理
        InvocationHandler deptProxy=new DyProxy<DeptDaoImpl>(ddi);
        DeptDao proxy= (DeptDao) Proxy.newProxyInstance(DeptDao.class.getClassLoader(),
                       new Class[]{DeptDao.class},
                       deptProxy);
        proxy.addDept();

        //還可以給UserDaoImpl做代理
        UserDaoImpl udimpl=new UserDaoImpl();
        InvocationHandler userProxy=new DyProxy<UserDaoImpl>(udimpl);
        //把代理對象 和被代理的綁定在一起
        UserDao proxy2=(UserDao)Proxy.newProxyInstance(UserDao.class.getClassLoader(),
                       new Class[]{UserDao.class},
                       userProxy);
        proxy2.registerUser();
    }
}