Java JDK動(dòng)態(tài)代理(AOP)用法及實(shí)現(xiàn)原理詳解
Java-JDK動(dòng)態(tài)代理(AOP)使用及實(shí)現(xiàn)原理分析
第一章:代理的介紹介紹:我們需要掌握的程度
動(dòng)態(tài)代理(理解) 基于反射機(jī)制
掌握的程度:
1.什么是動(dòng)態(tài)代理?
2.動(dòng)態(tài)代理能夠做什么?
后面我們?cè)谟肧pirng和Mybatis的時(shí)候,要理解怎么使用的.
1.什么是代理?
代理,在我們?nèi)粘I钪芯陀畜w現(xiàn),代購(gòu),中介,換ip,商家等等.
比如有一家美國(guó)的大學(xué),可以對(duì)全世界招生.留學(xué)中介(代理 )
留學(xué)中介(代理):幫助這家美國(guó)的學(xué)校招生,中介是學(xué)校的代理中介是代替學(xué)校完成招生功能代理特點(diǎn)
中介和代理他們要做的事情是一致的:招生中介是學(xué)校代理,學(xué)校是目標(biāo)家長(zhǎng)-------->中介(學(xué)校介紹,辦理入學(xué)手續(xù))---------->美國(guó)學(xué)校中介是代理,收取費(fèi)用 2.為什么要找中介
為什么要找中介?
1.中介是專業(yè)的,方便.
2.家長(zhǎng)現(xiàn)在不能自己去找學(xué)校。家長(zhǎng)沒(méi)有能力訪問(wèn)學(xué)校.或者美國(guó)學(xué)校不接收個(gè)人來(lái)訪
買(mǎi)東西都是商家賣(mài), 商家是某個(gè)商品的代理, 你個(gè)人買(mǎi)東西,肯定不會(huì)讓你接觸到廠家的.
第二章:靜態(tài)代理2.1 使用代理模式的作用 功能增強(qiáng):在你原有的功能上,增加了額外的功能.新增加的功能,叫做功能增強(qiáng)控制訪問(wèn):代理類(lèi)不讓你訪問(wèn)目標(biāo),例如商家不讓用戶訪問(wèn)廠家 2.2 實(shí)現(xiàn)代理的方式
1.靜態(tài)代理:
1)代理類(lèi)是自己手工實(shí)現(xiàn)的,自己創(chuàng)建一個(gè)java類(lèi),表示代理類(lèi)
2)同時(shí)你所要代理的目標(biāo)
特點(diǎn):1)實(shí)現(xiàn)簡(jiǎn)單2)容易理解。
模擬一個(gè)用戶購(gòu)買(mǎi)u盤(pán)的行為。
用戶是客戶端類(lèi)
商家:代理,代理某個(gè)品牌的u盤(pán)。
廠家:目標(biāo)類(lèi)。
三者的關(guān)系:用戶(客戶端)-—-商家(代理)-—-廠家(目標(biāo))
商家和廠家都是賣(mài)u盤(pán)的,他們完成的功能是一致的,都是賣(mài)u盤(pán)。
實(shí)現(xiàn)步驟:
實(shí)現(xiàn)步驟
1.創(chuàng)建一個(gè)接口,定義賣(mài)u盤(pán)的方法,表示你的廠家和商家做的事情2.創(chuàng)建廠家類(lèi),實(shí)現(xiàn)1步驟的接口3.創(chuàng)建商家,就是代理,也需要實(shí)現(xiàn)1步驟中的接口4.創(chuàng)建客戶端類(lèi),調(diào)用商家的方法買(mǎi)一個(gè)u盤(pán)
2.3 具體實(shí)現(xiàn)
實(shí)現(xiàn)步驟
package com.rango.service;public interface usbSell { /** * 定義一個(gè)方法 參數(shù) amount:表示一次購(gòu)買(mǎi)的數(shù)量,暫時(shí)不用 * 返回值表示一個(gè)u盤(pán)的價(jià)格 * @param amount * @return */ float sell(int amount);}
1.創(chuàng)建一個(gè)接口,定義賣(mài)u盤(pán)的方法,表示你的廠家和商家做的事情
2.創(chuàng)建廠家類(lèi),實(shí)現(xiàn)1步驟的接口
package com.rango.factory;import com.rango.service.usbSell;//目標(biāo)類(lèi):金士頓廠家,不接受用戶的單獨(dú)購(gòu)買(mǎi)public class UsbKingFactory implements usbSell { /** * 定義一個(gè)方法 參數(shù) amount:表示一次購(gòu)買(mǎi)的數(shù)量,暫時(shí)不用 * 返回值表示一個(gè)u盤(pán)的價(jià)格 * * @param amount * @return */ @Override//一個(gè)128G的U盤(pán)是85元.// 后期根據(jù)amount,可以實(shí)現(xiàn)不同的價(jià)格,例如10000個(gè),單擊是80,50000個(gè)75 public float sell(int amount) { return 85.0f*amount; }}
3.創(chuàng)建商家,就是代理,也需要實(shí)現(xiàn)1步驟中的接口
package com.rango.business;import com.rango.factory.UsbKingFactory;import com.rango.service.usbSell;//淘寶是一個(gè)商家,代理金士頓U盤(pán)的銷(xiāo)售public class TaoBao implements usbSell {// 聲明 商家代理的廠家具體是誰(shuí) private UsbKingFactory factory =new UsbKingFactory(); @Override// 實(shí)現(xiàn)銷(xiāo)售U盤(pán)功能 public float sell(int amount) {// 向廠家發(fā)送訂單,告訴廠家,我買(mǎi)了U盤(pán),廠家發(fā)貨// 發(fā)送給工廠,我需要的訂單,返回報(bào)價(jià) float price = factory.sell(amount);// 商家需要加價(jià)也就是代理要增加價(jià)格 price = price + 25;//在目標(biāo)類(lèi)的方法調(diào)用后,你做的其他功能,都是增強(qiáng)的意思 System.out.println('淘寶再給你返回一個(gè)優(yōu)惠券,或者紅包');// 增加的價(jià)格 return price; }}
4.創(chuàng)建客戶端類(lèi),調(diào)用商家的方法買(mǎi)一個(gè)u盤(pán)
import com.rango.business.TaoBao;public class shopMain { public static void main(String[] args){// 創(chuàng)建代理的商家淘寶對(duì)象 TaoBao taoBao = new TaoBao();// 我只向淘寶買(mǎi)一件產(chǎn)品,得到報(bào)價(jià) float price = taoBao.sell(2); System.out.println('購(gòu)買(mǎi)一件產(chǎn)品.淘寶的報(bào)價(jià)為: '+price); }}所以我們?cè)俅慰偨Y(jié)代理類(lèi)完成的功能:
目標(biāo)類(lèi)中方法的調(diào)用功能增強(qiáng)
所屬我們只有一個(gè)代理商,我們實(shí)際上可以寫(xiě)多個(gè)代理商,
2.4 靜態(tài)代理的優(yōu)缺點(diǎn)
我們?cè)俅慰偨Y(jié)一下靜態(tài)代理的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
實(shí)現(xiàn)簡(jiǎn)單容易簡(jiǎn)單
確定:當(dāng)你的項(xiàng)目中,目標(biāo)類(lèi)的代理類(lèi)很多的時(shí)候,有一下的缺點(diǎn)
當(dāng)目標(biāo)類(lèi)增加了,代理類(lèi)可能也需要成倍的增加當(dāng)你的接口中功能在增加了,或者修改了,會(huì)影響眾多的實(shí)現(xiàn)類(lèi),廠家類(lèi),代理都需要修改,影響比較多.
所以我們繼續(xù)學(xué)習(xí)動(dòng)態(tài)代理
第三章 動(dòng)態(tài)代理本章,我們所掌握的是
1)什么是動(dòng)態(tài)代理?
使用jdk的反射機(jī)制,創(chuàng)建對(duì)象的能力,創(chuàng)建的是代理類(lèi)的的對(duì)象.而不用我們創(chuàng)建類(lèi)文件,不用寫(xiě)java文件, 什么叫動(dòng)態(tài)?在程序執(zhí)行時(shí),調(diào)用jdk提供的方法才能創(chuàng)建代理類(lèi)的對(duì)象
2)知道動(dòng)態(tài)代理能做什么?
2.1 靜態(tài)代理和動(dòng)態(tài)代理模式的對(duì)比
在靜態(tài)代理中目標(biāo)很多的時(shí)候,可以使用動(dòng)態(tài)代理,避免靜態(tài)代理的缺點(diǎn)
在靜態(tài)代理中目標(biāo)類(lèi)很多時(shí)候,可以使用動(dòng)態(tài)代理,避免靜態(tài)代理的缺點(diǎn)。動(dòng)態(tài)代理中目標(biāo)類(lèi)即使很多,
代理類(lèi)數(shù)量可以很少,
當(dāng)你修改了接口中的方法時(shí),不會(huì)影響代理類(lèi)。
動(dòng)態(tài)代理:在程序執(zhí)行過(guò)程中,使用jdk的反射機(jī)制,創(chuàng)建代理類(lèi)對(duì)象,并動(dòng)態(tài)的指定要代理目標(biāo)類(lèi)。換句話說(shuō):動(dòng)態(tài)代理是一種創(chuàng)建java象的能力,讓你不用創(chuàng)建 TaoBao類(lèi)就能創(chuàng)建代理類(lèi)對(duì)象,除去了中間商
在java中,要想創(chuàng)建對(duì)象
創(chuàng)建類(lèi)文件,java 文件編譯為class 使用構(gòu)造方法,創(chuàng)建類(lèi)的對(duì)象 2.1 動(dòng)態(tài)代理的介紹
動(dòng)態(tài)代理是指代理類(lèi)對(duì)象在程序運(yùn)行時(shí)由JVM根據(jù)反射機(jī)制動(dòng)態(tài)生成的。動(dòng)態(tài)代理不需要定義代理類(lèi)的,java源文件。動(dòng)態(tài)代理其實(shí)就是jdk運(yùn)行期間,動(dòng)態(tài)創(chuàng)建class字節(jié)碼并加載到JVM。動(dòng)態(tài)代理的實(shí)現(xiàn)方式常用的有兩種:使用JDK代理,與通過(guò)CGLlB動(dòng)態(tài)代理。
動(dòng)態(tài)代理的實(shí)現(xiàn):
jdk動(dòng)態(tài)代理(理解):使用java反射包中的類(lèi)和接口實(shí)現(xiàn)動(dòng)態(tài)代理的功能,反射包java.lang.reflect,里面有三類(lèi):InvocationHandler,Method,Proxy cglib動(dòng)態(tài)代理(了解): cglib是第三方的工具庫(kù),創(chuàng)建代理對(duì)象 cglib的原理是繼承,cglib通過(guò)繼承目標(biāo)類(lèi),創(chuàng)建它的子類(lèi),在子類(lèi)中重寫(xiě)父類(lèi)中同名的方法,實(shí)現(xiàn)功能的修改。因?yàn)閏glib是繼承,重寫(xiě)方法,所以要求目標(biāo)類(lèi)不能是fina1的,方法也不能是final的。cglib的要求目標(biāo)類(lèi)比較寬松,只要能繼承就可以了。cglib在很多的框架中使用,比如mybatis,spring框架中都有使用。
package Test;import com.rango.Impl.HelloServiceImpl;import com.rango.service.HelloService;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class TestApp { public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {// HelloService service = new HelloServiceImpl();// service.sayhello('張三');// 以上是常規(guī)方法執(zhí)行sayhello// 下面我們使用反射機(jī)制進(jìn)行創(chuàng)建sayhello方法,核心Method(類(lèi)中的方法) HelloServiceImpl target = new HelloServiceImpl();// 獲取sayhello名稱對(duì)應(yīng)的Method類(lèi)對(duì)象// public Method getM ethod(String name, Class<?>... parameterTypes)// 加入,該方法的參數(shù)有多個(gè)該怎么辦?// parameterTypes參數(shù)是一個(gè)類(lèi)對(duì)象數(shù)組,按聲明的順序標(biāo)識(shí)方法的形式參數(shù)類(lèi)型。 Method method = HelloService.class.getMethod('sayhello', String.class);// 通過(guò)Metho可以執(zhí)行sayhello方法的調(diào)用 /* * public Object invoke(Object obj, Object... args) * 表示執(zhí)行方法的調(diào)用 * 參數(shù): * 1.Object,表示對(duì)象,要執(zhí)行這個(gè)對(duì)象的方法 * 2.Object...args,方法執(zhí)行時(shí)的參數(shù)值 * 返回值: * Object:方法執(zhí)行后的返回值 * */ Object ret = method.invoke(target, '李四'); }}
2.2 回顧反射 Method類(lèi)
Method類(lèi)的結(jié)構(gòu)圖
Class Method java.lang.Object java.lang.reflect.AccessibleObject java.lang.reflect.Executable java.lang.reflect.Method 2.2.1 class.getMethod
提出問(wèn)題?
public Method getMethod(String name, Class<?>... parameterTypes)
加入,該方法的參數(shù)有多個(gè)該怎么辦?
parameterTypes參數(shù)是一個(gè)類(lèi)對(duì)象數(shù)組,按聲明的順序標(biāo)識(shí)方法的形式參數(shù)類(lèi)型。
2.2.2 Method.invoke
public Object invoke(Object obj,Object... args)
* public Object invoke(Object obj, Object... args)* 表示執(zhí)行方法的調(diào)用* 參數(shù):* 1.Object,表示對(duì)象,要執(zhí)行這個(gè)對(duì)象的方法* 2.Object...args,方法執(zhí)行時(shí)的參數(shù)值* 返回值:* Object:方法執(zhí)行后的返回值*
到此這篇關(guān)于Java JDK動(dòng)態(tài)代理(AOP)用法及實(shí)現(xiàn)原理詳解的文章就介紹到這了,更多相關(guān)Java-AOP用法及實(shí)現(xiàn)原理分析內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!
相關(guān)文章:
1. 部署vue+Springboot前后端分離項(xiàng)目的步驟實(shí)現(xiàn)2. html清除浮動(dòng)的6種方法示例3. JavaScript實(shí)現(xiàn)組件化和模塊化方法詳解4. Python基于Serializer實(shí)現(xiàn)字段驗(yàn)證及序列化5. idea設(shè)置自動(dòng)導(dǎo)入依賴的方法步驟6. PHP字符串前后字符或空格刪除方法介紹7. 網(wǎng)頁(yè)中img圖片使用css實(shí)現(xiàn)等比例自動(dòng)縮放不變形(代碼已測(cè)試)8. Python安裝并操作redis實(shí)現(xiàn)流程詳解9. JSP之表單提交get和post的區(qū)別詳解及實(shí)例10. AJAX實(shí)現(xiàn)數(shù)據(jù)的增刪改查操作詳解【java后臺(tái)】
