我們先來介紹下什麼是代理。
(學習影片分享:java影片教學)
代理程式是一種設計模式,它的核心思想,是將對目標的存取轉移到代理物件上。這樣做的好處就是,目標物件在不改變程式碼的情況下,可以透過代理物件加上一些額外的功能。這是一種程式設計思想,在不改變原有程式碼的情況下,透過代理程式增加一些擴充功能。
代理程式如圖所示,使用者存取代理對象,代理對象透過存取目標對象,來達到使用者存取目標對象的目的,
public interface IBlogService { void writeBlog(); }目標對象實現了目標接口,程式碼如下:
public class BlogService implements IBlogService { @Override public void writeBlog() { System.out.println("i'm writing..."); } }靜態代理對象,透過建構方法獲取到目標對象,並實現了目標接口,在目標接口的方法裡調用了目標對象的方法,代碼如下:
public class BlogStaticProxy implements IBlogService{ private IBlogService blogService; public BlogStaticProxy(IBlogService blogService) { this.blogService = blogService; } @Override public void writeBlog() { System.out.println("start writing..."); blogService.writeBlog(); System.out.println("end writing..."); } }靜態代理對象,通過構造方法獲取到目標對象,並實現了目標接口,在目標接口的方法裡呼叫了目標對象的方法,代碼如下:
public class BlogStaticProxy implements IBlogService{ private IBlogService blogService; public BlogStaticProxy(IBlogService blogService) { this.blogService = blogService; } @Override public void writeBlog() { System.out.println("start writing..."); blogService.writeBlog(); System.out.println("end writing..."); } }測試:
public class TestStaticProxy { public static void main(String[] args) { IBlogService target = new BlogService(); BlogStaticProxy proxy = new BlogStaticProxy(target); proxy.write(); } }
start writing… i’m writing… end writing…靜態代理,在不修改目標對象的情況下,可以通過代理對象做額外的擴充功能。但靜態方法不是很靈活,如果目標介面的程式碼修改,目標物件和代理物件都需要修改。 動態代理在一定程度上避免這種情況,動態代理不需要代理對象實現目標接口,並且上在java 虛擬機的內存中動態的生成代理對象Jdk動態對象Jdk的動態代理由Proxy這個類別來生成,它有三個參數:ClassLoader loader,:指定目前目標物件使用類別載入器,取得載入器的方法是固定的Class>[] interfaces,:目標物件實現的介面的類型,使用泛型方式確認類型#InvocationHandler h:事件處理,執行目標物件的方法時,會觸發事件處理器的方法,會把目前執行目標物件的方法作為參數傳入
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException { }Jdk的動態代理程式碼如下:
public class JdkBlogProxyFactory { private Object target; public JdkBlogProxyFactory(Object target) { this.target = target; } public Object newInstance() { return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), (proxy, method, args) -> { System.out.println("start writing"); Object o = method.invoke(target, args); System.out.println("end writing"); return o; }); } }測試類別:
public class TestJdkProxy { public static void main(String[] args) { IBlogService target = new BlogService(); System.out.println(target.getClass()); // 给目标对象,创建代理对象 IBlogService proxy = (IBlogService) new JdkBlogProxyFactory(target).newInstance(); // class $Proxy0 内存中动态生成的代理对象 System.out.println(proxy.getClass()); // 执行方法 【代理对象】 proxy.writeBlog(); } }控制台列印如下:
class com.forezp.proxy.BlogService class com.sun.proxy.$Proxy0 start writing i'm writing... end writingCGLib動態代理CGLib採用了非常底層的字節碼技術,其原理是透過字節碼技術為一個類別建立子類,並在子類中採用方法攔截的技術攔截所有父類別方法的調用,順勢織入橫切邏輯。 CglibBlogFactory代理工廠類別如下:
public class CglibBlogFactory implements MethodInterceptor { private Object target; public CglibBlogFactory(Object target) { this.target = target; } //给目标对象创建一个代理对象 public Object getProxyInstance() { //1.工具类 Enhancer en = new Enhancer(); //2.设置父类 en.setSuperclass(target.getClass()); //3.设置回调函数 en.setCallback(this); //4.创建子类(代理对象) return en.create(); } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("start writing..."); //执行目标对象的方法 Object returnValue = method.invoke(target, objects); System.out.println("end writing..."); return returnValue; } }測試類別:
public class TestCglib { public static void main(String[] args) { IBlogService target = new BlogService(); //代理对象 IBlogService proxy = (IBlogService) new CglibBlogFactory(target).getProxyInstance(); //执行代理对象的方法 proxy.writeBlog(); } }運行程序,控制台列印:
start writing... i'm writing... end writing...相關推薦:
以上是java代理模式介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!
陳述
本文轉載於:掘金。如有侵權,請聯絡admin@php.cn刪除

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章
Windows 11 KB5054979中的新功能以及如何解決更新問題
3 週前ByDDD
如何修復KB5055523無法在Windows 11中安裝?
2 週前ByDDD
Inzoi:如何申請學校和大學
4 週前ByDDD
如何修復KB5055518無法在Windows 10中安裝?
2 週前ByDDD
在哪裡可以找到Atomfall中的站點辦公室鑰匙
4 週前ByDDD

熱工具

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

禪工作室 13.0.1
強大的PHP整合開發環境