Java JDK動態(tài)代理(AOP)用法及實現(xiàn)原理詳解
Java-JDK動態(tài)代理(AOP)使用及實現(xiàn)原理分析
第一章:代理的介紹
介紹:我們需要掌握的程度
動態(tài)代理(理解) 基于反射機(jī)制
掌握的程度:
1.什么是動態(tài)代理?
2.動態(tài)代理能夠做什么?
后面我們在用Spirng和Mybatis的時候,要理解怎么使用的.
1.什么是代理?
代理,在我們?nèi)粘I钪芯陀畜w現(xiàn),代購,中介,換ip,商家等等.
比如有一家美國的大學(xué),可以對全世界招生.留學(xué)中介(代理 )
留學(xué)中介(代理):幫助這家美國的學(xué)校招生,中介是學(xué)校的代理中介是代替學(xué)校完成招生功能
代理特點
中介和代理他們要做的事情是一致的:招生中介是學(xué)校代理,學(xué)校是目標(biāo)家長-------->中介(學(xué)校介紹,辦理入學(xué)手續(xù))---------->美國學(xué)校中介是代理,收取費用 2.為什么要找中介
為什么要找中介?
1.中介是專業(yè)的,方便.
2.家長現(xiàn)在不能自己去找學(xué)校。家長沒有能力訪問學(xué)校.或者美國學(xué)校不接收個人來訪
買東西都是商家賣, 商家是某個商品的代理, 你個人買東西,肯定不會讓你接觸到廠家的.
第二章:靜態(tài)代理
2.1 使用代理模式的作用 功能增強(qiáng):在你原有的功能上,增加了額外的功能.新增加的功能,叫做功能增強(qiáng)控制訪問:代理類不讓你訪問目標(biāo),例如商家不讓用戶訪問廠家 2.2 實現(xiàn)代理的方式
1.靜態(tài)代理:
1)代理類是自己手工實現(xiàn)的,自己創(chuàng)建一個java類,表示代理類
2)同時你所要代理的目標(biāo)
特點:1)實現(xiàn)簡單2)容易理解。
模擬一個用戶購買u盤的行為。
用戶是客戶端類
商家:代理,代理某個品牌的u盤。
廠家:目標(biāo)類。
三者的關(guān)系:用戶(客戶端)-—-商家(代理)-—-廠家(目標(biāo))
商家和廠家都是賣u盤的,他們完成的功能是一致的,都是賣u盤。
實現(xiàn)步驟:
實現(xiàn)步驟
1.創(chuàng)建一個接口,定義賣u盤的方法,表示你的廠家和商家做的事情
2.創(chuàng)建廠家類,實現(xiàn)1步驟的接口
3.創(chuàng)建商家,就是代理,也需要實現(xiàn)1步驟中的接口
4.創(chuàng)建客戶端類,調(diào)用商家的方法買一個u盤
2.3 具體實現(xiàn)
實現(xiàn)步驟
package com.rango.service; public interface usbSell { /** * 定義一個方法 參數(shù) amount:表示一次購買的數(shù)量,暫時不用 * 返回值表示一個u盤的價格 * @param amount * @return */ float sell(int amount); }
1.創(chuàng)建一個接口,定義賣u盤的方法,表示你的廠家和商家做的事情
2.創(chuàng)建廠家類,實現(xiàn)1步驟的接口
package com.rango.factory; import com.rango.service.usbSell; //目標(biāo)類:金士頓廠家,不接受用戶的單獨購買 public class UsbKingFactory implements usbSell { /** * 定義一個方法 參數(shù) amount:表示一次購買的數(shù)量,暫時不用 * 返回值表示一個u盤的價格 * * @param amount * @return */ @Override //一個128G的U盤是85元. // 后期根據(jù)amount,可以實現(xiàn)不同的價格,例如10000個,單擊是80,50000個75 public float sell(int amount) { return 85.0f*amount; } }
3.創(chuàng)建商家,就是代理,也需要實現(xiàn)1步驟中的接口
package com.rango.business; import com.rango.factory.UsbKingFactory; import com.rango.service.usbSell; //淘寶是一個商家,代理金士頓U盤的銷售 public class TaoBao implements usbSell { // 聲明 商家代理的廠家具體是誰 private UsbKingFactory factory =new UsbKingFactory(); @Override // 實現(xiàn)銷售U盤功能 public float sell(int amount) { // 向廠家發(fā)送訂單,告訴廠家,我買了U盤,廠家發(fā)貨 // 發(fā)送給工廠,我需要的訂單,返回報價 float price = factory.sell(amount); // 商家需要加價也就是代理要增加價格 price = price + 25; //在目標(biāo)類的方法調(diào)用后,你做的其他功能,都是增強(qiáng)的意思 System.out.println("淘寶再給你返回一個優(yōu)惠券,或者紅包"); // 增加的價格 return price; } }
4.創(chuàng)建客戶端類,調(diào)用商家的方法買一個u盤
import com.rango.business.TaoBao; public class shopMain { public static void main(String[] args){ // 創(chuàng)建代理的商家淘寶對象 TaoBao taoBao = new TaoBao(); // 我只向淘寶買一件產(chǎn)品,得到報價 float price = taoBao.sell(2); System.out.println("購買一件產(chǎn)品.淘寶的報價為: "+price); } }所以我們再次總結(jié)代理類完成的功能:
目標(biāo)類中方法的調(diào)用功能增強(qiáng)
所屬我們只有一個代理商,我們實際上可以寫多個代理商,
2.4 靜態(tài)代理的優(yōu)缺點
我們再次總結(jié)一下靜態(tài)代理的優(yōu)缺點
優(yōu)點:
實現(xiàn)簡單容易簡單
確定:當(dāng)你的項目中,目標(biāo)類的代理類很多的時候,有一下的缺點
當(dāng)目標(biāo)類增加了,代理類可能也需要成倍的增加當(dāng)你的接口中功能在增加了,或者修改了,會影響眾多的實現(xiàn)類,廠家類,代理都需要修改,影響比較多.
所以我們繼續(xù)學(xué)習(xí)動態(tài)代理
第三章 動態(tài)代理
本章,我們所掌握的是
1)什么是動態(tài)代理?
使用jdk的反射機(jī)制,創(chuàng)建對象的能力,創(chuàng)建的是代理類的的對象.而不用我們創(chuàng)建類文件,不用寫java文件, 什么叫動態(tài)?在程序執(zhí)行時,調(diào)用jdk提供的方法才能創(chuàng)建代理類的對象
2)知道動態(tài)代理能做什么?
2.1 靜態(tài)代理和動態(tài)代理模式的對比
在靜態(tài)代理中目標(biāo)很多的時候,可以使用動態(tài)代理,避免靜態(tài)代理的缺點
在靜態(tài)代理中目標(biāo)類很多時候,可以使用動態(tài)代理,避免靜態(tài)代理的缺點。
動態(tài)代理中目標(biāo)類即使很多,
代理類數(shù)量可以很少,
當(dāng)你修改了接口中的方法時,不會影響代理類。
動態(tài)代理:在程序執(zhí)行過程中,使用jdk的反射機(jī)制,創(chuàng)建代理類對象,并動態(tài)的指定要代理目標(biāo)類。
換句話說:動態(tài)代理是一種創(chuàng)建java象的能力,讓你不用創(chuàng)建 TaoBao類就能創(chuàng)建代理類對象,除去了中間商
在java中,要想創(chuàng)建對象
創(chuàng)建類文件,java 文件編譯為class 使用構(gòu)造方法,創(chuàng)建類的對象 2.1 動態(tài)代理的介紹
動態(tài)代理是指代理類對象在程序運行時由JVM根據(jù)反射機(jī)制動態(tài)生成的。動態(tài)代理不需要定義代理類的,java源文件。動態(tài)代理其實就是jdk運行期間,動態(tài)創(chuàng)建class字節(jié)碼并加載到JVM。動態(tài)代理的實現(xiàn)方式常用的有兩種:使用JDK代理,與通過CGLlB動態(tài)代理。
動態(tài)代理的實現(xiàn):
jdk動態(tài)代理(理解):使用java反射包中的類和接口實現(xiàn)動態(tài)代理的功能,反射包java.lang.reflect,里面有三類:InvocationHandler,Method,Proxy cglib動態(tài)代理(了解): cglib是第三方的工具庫,創(chuàng)建代理對象 cglib的原理是繼承,cglib通過繼承目標(biāo)類,創(chuàng)建它的子類,在子類中重寫父類中同名的方法,實現(xiàn)功能的修改。因為cglib是繼承,重寫方法,所以要求目標(biāo)類不能是fina1的,方法也不能是final的。cglib的要求目標(biāo)類比較寬松,只要能繼承就可以了。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(類中的方法) HelloServiceImpl target = new HelloServiceImpl(); // 獲取sayhello名稱對應(yīng)的Method類對象 // public Method getM ethod(String name, Class<?>... parameterTypes) // 加入,該方法的參數(shù)有多個該怎么辦? // parameterTypes參數(shù)是一個類對象數(shù)組,按聲明的順序標(biāo)識方法的形式參數(shù)類型。 Method method = HelloService.class.getMethod("sayhello", String.class); // 通過Metho可以執(zhí)行sayhello方法的調(diào)用 /* * public Object invoke(Object obj, Object... args) * 表示執(zhí)行方法的調(diào)用 * 參數(shù): * 1.Object,表示對象,要執(zhí)行這個對象的方法 * 2.Object...args,方法執(zhí)行時的參數(shù)值 * 返回值: * Object:方法執(zhí)行后的返回值 * */ Object ret = method.invoke(target, "李四"); } }
2.2 回顧反射 Method類
Method類的結(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
提出問題?
public Method getMethod(String name, Class<?>... parameterTypes)
加入,該方法的參數(shù)有多個該怎么辦?
parameterTypes參數(shù)是一個類對象數(shù)組,按聲明的順序標(biāo)識方法的形式參數(shù)類型。
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,表示對象,要執(zhí)行這個對象的方法 * 2.Object...args,方法執(zhí)行時的參數(shù)值 * 返回值: * Object:方法執(zhí)行后的返回值 *
到此這篇關(guān)于Java JDK動態(tài)代理(AOP)用法及實現(xiàn)原理詳解的文章就介紹到這了,更多相關(guān)Java-AOP用法及實現(xiàn)原理分析內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
IDEA社區(qū)版創(chuàng)建spring boot項目的安裝插件的圖文教程
這篇文章主要介紹了IDEA社區(qū)版創(chuàng)建spring boot項目的安裝插件,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11SpringSecurity怎樣使用注解控制權(quán)限
這篇文章主要介紹了SpringSecurity怎樣使用注解控制權(quán)限的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06Springmvc如何返回xml及json格式數(shù)據(jù)
這篇文章主要介紹了Springmvc如何返回xml及json格式數(shù)據(jù),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-09-09Mybatis查詢Sql結(jié)果未映射到對應(yīng)得實體類上的問題解決
使用mybatis查詢表數(shù)據(jù)得時候,發(fā)現(xiàn)對應(yīng)得實體類字段好多都是null,本文主要介紹了Mybatis查詢Sql結(jié)果未映射到對應(yīng)得實體類上的問題解決,具有一定的參考價值,感興趣的可以了解一下2024-02-02Java編程中使用throw關(guān)鍵字拋出異常的用法簡介
這篇文章主要介紹了Java編程中使用throw關(guān)鍵字拋出異常的用法,是Java入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2015-11-11Springboot利于第三方服務(wù)進(jìn)行ip定位獲取省份城市
本文主要介紹了Springboot利于第三方服務(wù)進(jìn)行ip定位獲取省份城市,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07spring boot在啟動項目之后執(zhí)行的實現(xiàn)方法
在開發(fā)時有時候需要在整個應(yīng)用開始運行時執(zhí)行一些特定代碼,比如初始化環(huán)境,下面這篇文章就來給大家介紹了關(guān)于spring boot在啟動項目之后執(zhí)行自己要執(zhí)行的東西的實現(xiàn)方法,文中給出了詳細(xì)的示例代碼,需要的朋友可以參考下。2017-09-09