記錄下jdk動態代理
一個小白,記錄學習遇到的坑
最近正在學習框架,初步了解了下什么是動態代理,記錄下來,方便以后復習和修改,
首先代理是啥意思?
個人理解:
我們網購時,在淘寶、京東等平臺上購買某件商品后,如果我們不滿意,我們是不是可以退款?這就是起到一個代理的作用,
代理的作用
1、通俗的來講,起到一個控制和增強的作用,
- 控制:上面的網購可以解釋,
- 增強:可以理解為中間商賺差價,
代理的分類
分為靜態代理和動態代理
下面說個例子來講講靜態代理
靜態代理
我們先定義一個U盤的介面
package com.han.usb;
public interface Usb {
float usbSell(int amount);
}
下面有個制作U盤的廠家,制作u盤,
package com.han.factory;
import com.han.usb.Usb;
public class UsbFactory implements Usb {
public float usbSell(int amount) {
float price=85.0f;
System.out.println("廠家出廠:"+price);
return price;
}
}
下面在創建個代理商,廠家通過這個代理商去聯系更多的人,提高收入,
代理商也要吃飯是不是,所以啊這個代理商就賺了億點點錢,并且還對
顧客說我們已經給了一張優惠卷,
package com.han.Tao;
import com.han.factory.UsbFactory;
import com.han.usb.Usb;
public class Taoproxy implements Usb {
@Override
public float usbSell(int amount) {
UsbFactory usbFactory=new UsbFactory();
float price=usbFactory.usbSell(amount);
price = (float) (price+25.0);
System.out.println("商家給你一個優惠卷,優惠了5快");
return price;
}
}
今天,小王看中了這個U盤,就找這個代理商買,
package com.han.customer;
import com.han.Tao.Taoproxy;
import com.han.usb.Usb;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class CustomerShop {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Taoproxy taoproxy=new Taoproxy();
// float price=taoproxy.usbSell(1);
Method method = Usb.class.getMethod("usbSell",int.class);
// int
// java.lang.Integer
// System.out.println(int.class.getName());
// System.out.println(Integer.class.getName());
float price= (float) method.invoke(taoproxy,1);
System.out.println("真好,真便宜,最后只花了"+price);
}
}
買完后,美滋滋!!!

這就是一個簡單的靜態例子,那么這么做的好處是什么了?
- 假如你的手里有個class檔案,你完全不能改動其中的內容,但是這里面的功能不能實作你目前的業務,這時我們就可以通過代理來實作,
哈哈,這個例子我也不知道準不準確,我就繼續編下去哈!
改動一個還好,我們只需要手動寫幾個代理類,但是如果改動100個了,哈哈,我回吐,
就沒有什么辦法嗎? 有辦法呀,什么辦法了? 就是動態代理
動態代理
我目前只學了jdk動態代理,小聲比比,
所謂的動態代理就是不能手動寫代理商,交個jvm去動態生成,我們只需要寫清楚我們所需要的功能,
那么怎么來實作動態代理了?
- 我們要實作一個介面InvocationHandler和創建一個代理(代理商)物件
我也沒有完全搞明白是怎么創建出來的代理,今天先記錄下來,以后在來補充,
先來實作這個介面
package com.han.Tao;
import com.han.usb.Usb;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyInvocationHandler implements InvocationHandler {
public Usb target;
public MyInvocationHandler(Usb target) {
this.target=target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//
float price= (float) method.invoke(target,args);
price=price+30.0f;
System.out.println("商家給你優惠卷");
return price;
}
}
解釋:
實作這個介面就是要重寫這個invoke方法,這個方法的引數解釋
下面的引數解釋僅僅在我目前的理解下做出的解釋,錯誤重重!!!
- proxy:個人認為就是創建的代理物件
- method:顯而易見就是我們需要呼叫的方法
- args:傳入的引數,用在呼叫method方法時傳入的引數
- target:就是你要代理的目標物件,也就是廠家
好,我們需要處理的業務邏輯代理已經完成了
下面再來創建代理類Proxy
創建代理類用到Proxy類中的一個靜態方法,
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces, InvocationHandler h)
眨眼一看,我的媽呀,這都是啥?
我是暈,不知道您了?
來解釋下引數:
- loader :類加載,加載一個類的位元組碼檔案
- interfaces: 類實作的介面(可能有多個介面)資訊
- h :我猜,這個就是proxy和invocationHandler連接起來的關鍵
這也就說明了JDK動態代理是需要有介面的
類加載沒有了解過,勿噴啊!!!
package com.han.customer;
import com.han.Tao.MyInvocationHandler;
import com.han.factory.UsbFactory;
import com.han.usb.Usb;
import java.lang.reflect.Proxy;
public class MyProxy {
public static void main(String[] args) {
UsbFactory factory = new UsbFactory();
MyInvocationHandler myInvocationHandler = new MyInvocationHandler(factory);
Usb proxy = (Usb) Proxy.newProxyInstance(factory.getClass().getClassLoader(), factory.getClass().getInterfaces(), myInvocationHandler);
float price = proxy.usbSell(1);
System.out.println("真便宜,只用了"+price);
}
}
proxy.usbSell(1)執行到這兒時,會自動跳轉到method.invoke(target,args),執行該方法,
我猜啊
這里的usbSell通過某種方式傳給了method引數
而1則傳給了args引數
今天先記錄到這兒,勿噴啊,小白一個,我會努力的!!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/178304.html
標籤:Java
下一篇:從零開始可以這樣學python
