1. 程式人生 > 實用技巧 >手寫@koa/router原始碼

手寫@koa/router原始碼

技術標籤:javajava後端

1、靜態代理

1、角色分析:

  • 抽象角色:共同完成的一件事情,一般會使用介面或者抽象類來解決
  • 真實角色:被代理的角色
  • 代理角色:代理真實角色,代理真實角色後,我們一般會做一些附屬操作。
  • 客戶:訪問代理物件的人!

2、程式碼步驟:

//結婚
interface Marry{
void HappyMarry();
}


2. ```java
// 你去結婚
class You implements Marry{

    @Override
    public void HappyMarry() {
        System.out.println("我要結婚了");
    }
}

// 代理物件,幫助你結婚
class WeddingCompany implements Marry{
private Marry target;

   public WeddingCompany(Marry target) {
       this.target = target;
   }

   @Override
   public void HappyMarry() {
       before(); // 幫你佈置現場
       this.target.HappyMarry(); // 你去結婚
       after(); // 收尾款 
   }
   private void before() {
       System.out.println("佈置現場");
   }

   private void after() {
       System.out.println("收尾款");
   }

}


4. ```java
public class StaticProxy {
    public static void main(String[] args) {
        // 代理物件幫你佈置現場  收尾款
        WeddingCompany weddingCompany = new WeddingCompany(new You());
        weddingCompany.HappyMarry();// 你只需要自己結婚即可
    }
}

3、靜態代理的好處:

  • 可以使真實角色的操作更加純粹!不用去關注一些公共的業務
  • 公共也就交給代理角色!實現了業務的分工!
  • 公共業務發生擴充套件的時候,方便集中管理!

4、缺點:

  • 一個真實角色就會產生一個代理角色,程式碼量會翻倍,開發效率會變低

2、動態代理

1、JDK 動態代理

1、使用 JDK 動態代理,使用 Proxy類裡面的方法建立代理物件

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-JMuZaHNI-1607480522120)(img/image-20200922200209368.png)]

Proxy 提供用於建立動態代理類和例項的靜態方法

呼叫 newProxyInstance 方法

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-ao7agMRD-1607480522123)(img/image-20200922200457006.png)]

方法中有三個引數:

  • 第一個引數:類載入器

  • 第二個引數:增強方法所在的類,這個類實現的介面,支援多個介面

  • 第三個引數:實現這個介面 InvocationHandler,建立代理物件,寫增強的方法

2、步驟

1、建立介面,定義方法

public interface UserDao {
    int add(int a,int b);
    String update(String id);
}

2、建立介面實現類,實現方法

public class UserDaoImpl implements UserDao {
    @Override
    public int add(int a, int b) {
        System.out.println("add方法執行了。。。。");
        return a+b;
    }

    @Override
    public String update(String id) {
        System.out.println("update方法執行了。。。。");
        return id;
    }
}

3、使用 Proxy 類建立介面代理物件

package com.yb.spring5;

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

public class JDKProxy {
    public static void main(String[] args) {
        //建立介面實現類代理物件
        Class[] interfaces = {UserDao.class};

/*        Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new InvocationHandler() {
            @Override //匿名內部類,或者建立一個類,然後這裡寫上類物件
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                return null;
            }
        });*/

        UserDaoImpl userDao = new UserDaoImpl();
        //獲取代理物件
        UserDao dao = (UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new UserDaoProxy(userDao));
        //呼叫對應的方法
        int res = dao.add(1, 2);
        System.out.println("結果:"+res);
    }
}

//建立代理物件程式碼
class UserDaoProxy implements InvocationHandler{

    //1、建立的是誰的代理物件,把誰傳遞過來
    private Object obj;
    //有引數構造傳遞
    public UserDaoProxy(Object obj){
        this.obj = obj;
    }

    //增強的邏輯
    //引數 proxy:代理物件
    //引數 method:當前的方法
    //引數 args:引數
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //方法之前
        System.out.println("方法之前執行..."+method.getName()+"方法:傳遞的引數"+ Arrays.toString(args));
        //被增強的方法執行
        Object res = method.invoke(obj, args);
        //方法之後
        System.out.println("方法之後執行..."+obj);

        return res;
    }
}
//結果
方法之前執行...add方法:傳遞的引數[1, 2]
add方法執行了。。。。
方法之後執行[email protected]
結果:3

動態代理的好處:

  • 可以使真實角色的操作更加純粹!不用去關注一些公共的業務
  • 公共也就交給代理角色!實現了業務的分工!
  • 公共業務發生擴充套件的時候,方便集中管理!
  • 一個動態代理類代理的是一個介面,一般就是對應的一類業務
    方法:傳遞的引數[1, 2]
    add方法執行了。。。。
    方法之後執行…[email protected]
    結果:3



動態代理的好處:

* 可以使真實角色的操作更加純粹!不用去關注一些公共的業務
* 公共也就交給代理角色!實現了業務的分工!
* 公共業務發生擴充套件的時候,方便集中管理!
* 一個動態代理類代理的是一個介面,一般就是對應的一類業務
* 一個動態代理類可以代理多個類,只要是實現了同一個介面即可!