手寫@koa/router原始碼
阿新 • • 發佈:2020-11-16
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
類裡面的方法建立代理物件
Proxy
提供用於建立動態代理類和例項的靜態方法
呼叫 newProxyInstance 方法
方法中有三個引數:
-
第一個引數:類載入器
-
第二個引數:增強方法所在的類,這個類實現的介面,支援多個介面
-
第三個引數:實現這個介面 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
動態代理的好處:
* 可以使真實角色的操作更加純粹!不用去關注一些公共的業務
* 公共也就交給代理角色!實現了業務的分工!
* 公共業務發生擴充套件的時候,方便集中管理!
* 一個動態代理類代理的是一個介面,一般就是對應的一類業務
* 一個動態代理類可以代理多個類,只要是實現了同一個介面即可!