Java 類的加載與動態代理

類的加載

 類加載器:類加載器是負責加載類的對象。將class文件(硬盤)加載到內存生成Class對象。
 使用 類.class.getClassLoader() 獲得加載自己的類加載器
 類加載器加載機制:全盤負責委託機制
全盤負責:A類如果要使用B類(不存在),A類加載器C必須負責加載B類。

委託機制:A類加載器如果要加載資源B,必須詢問父類加載是否加載。
	如果加載,將直接使用。
	如果沒有機制,自己再加載。

 採用 全盤負責委託機制 保證一個class文件只會被加載一次,形成一個Class對象。
 注意:

  1. 如果一個class文件,被兩個類加載器加載,將是兩個對象。
  2. 自定義類加載,可以將一個class文件加載多次。

動態代理

  Java代理有JDK動態代理,主要使用的是Java反射機制(即java.lang.reflect包)。
  動態代理:程序運行時,使用JDK提供工具類(Proxy),動態創建一個類,此類一般用於代理。
  代理:你 – 代理(增強) – 廠商
  代理類:
  目標類:被代理的
  動態代理使用前提:必須有接口

  Object proxyObj = Proxy.newProxyInstance(參數1,參數2,參數3);
  參數1:ClassLoader,負責將動態創建類,加載到內存。 當前類.class.getClassLoader();
  參數2:Class[] interfaces ,代理類需要實現的所有接口(確定方法),被代理類實例.getClass().getInterfaces();
  參數3:InvocationHandler, 請求處理類,代理類不具有任何功能,代理類的每一個方法執行時,調用處理類invoke方法。

  invoke(Object proxy ,Method method,Object[] args)
  參數1:代理實例
  參數2:當前執行的方法
  參數3:方法實際參數。

public interface UserInter {
    public void eat();
    public void study();
}
public class UserDaoImpl implements UserInter{

    @Override
    public void eat() {
        System.out.println("正在吃飯");
    }

    @Override
    public void study() {
        System.out.println("正在學習");
    }
}

public class UserProxyImpl implements UserInter{
    private UserDaoImpl imp;
    public UserProxyImpl(){}
    public UserProxyImpl(UserDaoImpl imp){
        this.imp = imp;
    }

    @Override
    public void eat() {
        System.out.println("開始吃飯了");
        imp.eat();
        System.out.println("吃飯結束了");
    }

    @Override
    public void study() {
        imp.study();
    }
}
public class UserProxyDynamicImpl implements InvocationHandler {

    public Object object;
    public UserProxyDynamicImpl(Object obj){
        this.object = obj;
    }


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(object);
        //System.out.println(proxy);
        //(原本對象)自己調用自己
        method.invoke(object, args);
        return null;
    }
public class ProxyTest {
    public static void main(String[] args){
        UserDaoImpl imp = new UserDaoImpl();
        //靜態代理類
        UserProxyImpl proxy = new UserProxyImpl(imp);
        proxy.eat();

		//1.原本類必須要接口
        UserDaoImpl user=  new UserDaoImpl();
        //2.實現代理類的InvocationHandler接口
        InvocationHandler ih = new UserProxyDongtaiImpl(user);
        //3.動態創建代理類
        UserInter proxy = (UserInter) Proxy.newProxyInstance(UserDaoImpl.class.getClassLoader(),
                new Class[]{UserInter.class},ih);
        proxy.eat();
        proxy.study();
    }

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章