日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java代理的原理及应用

發布時間:2023/12/13 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java代理的原理及应用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

什么是代理模式?

  定義

    為其他對象提供一種代理以控制對這個對象的訪問。在某些情況下,一個對象不適合或者不能直接引用另一個對象,而代理對象可以在客戶端和目標對象之間起到中介的作用。

                                                                  ——百度百科

  代理模式的角色

  抽象角色:代理對象和真實對象的共同接口

  代理角色:代理對象角色內部含有對真實對象的引用,從而可以操作真實對象,同時代理對象提供與真實對象相同的接口以便在任何時刻都能夠代替真實對象。同時,代理對象可以在執行真實對象操作時,附加其他的操作,相當于對真實對象進行封裝。

  真實角色:代理角色所代表的真實對象,是我們最終要引用的對象。

  示意圖

    

代理模式的分類及使用

  • 靜態代理

1 package staticProxy; 2 3 // 抽象角色,真是對象與代理對象的共同接口 4 public interface Subject { 5 public void request(); 6 } 抽象角色 1 package staticProxy; 2 3 //代理對象,用來被客戶端直接調用的類,內部被注入真實對象,可以在調用真是對象的方法前后做預處理和后處理 4 public class ProxyClass implements Subject { 5 6 Subject subject; 7 8 ProxyClass (Subject subject) { 9 this.subject = subject; 10 } 11 12 @Override 13 public void request() { 14 System.out.println("prefix-process!"); 15 subject.request(); 16 System.out.println("suffix-process!"); 17 } 18 19 } 代理角色 1 package staticProxy; 2 3 //真實對象,委托類 4 public class RealClass implements Subject { 5 6 @Override 7 public void request() { 8 System.out.println("I'm realClass!"); 9 } 10 11 } 真實角色 1 package staticProxy; 2 3 //客戶端 4 public class StaticProxy { 5 public static void main(String[] args) { 6 Subject subject = new ProxyClass(new RealClass()); 7 8 subject.request(); 9 } 10 } 客戶端

    靜態代理的缺點很顯著,對每一個委托類都需要創建一個代理類,為了解決這個問題,java提供了動態代理。

  • 動態代理

    抽象角色與真實角色的定義和靜態代理完全一致,這里不再重復定義

    動態代理類需要繼承自InvocationHandler接口,并實現其中的invoke方法。

1 package dynamicProxy; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 6 public class ProxyClass implements InvocationHandler { 7 8 Object subject; 9 10 public ProxyClass(Object subject) { 11 this.subject = subject; 12 } 13 14 @Override 15 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 16 System.out.println("prefix-process!"); 17 method.invoke(subject, args); 18 System.out.println("suffix-process!"); 19 return null; 20 } 21 22 } 動態代理類 1 package dynamicProxy; 2 3 import java.lang.reflect.Proxy; 4 5 public class DynamicProxy { 6 public static void main(String[] args) { 7 8 Subject subject = (Subject) Proxy.newProxyInstance(RealClass.class.getClassLoader(), 9 new Class[] {Subject.class}, new ProxyClass(new RealClass())); 10 11 subject.request(); 12 } 13 } 客戶端

動態代理的實現原理

動態代理的實現主要依賴于java.lang.reflect.InvocationHandler接口與java.lang.reflect.Proxy類,其實現原理是基于java的反射技術。

InvocationHandler接口

    動態代理類需要繼承自InvocationHandler接口,此接口中只包含一個方法invoke方法,接口原型如下:

1 package java.lang.reflect; 2 3 public interface InvocationHandler { 4 5 /** 6 * proxy:代表代理對象本身,用于調用本代理對象的其他方法 7 * method:代表正在被調用的委托類的方法 8 * args:代表調用方法的參數 9 */ 10 public Object invoke(Object proxy, Method method, Object[] args) 11 throws Throwable; 12 } InvocationHandler

Proxy類

    Proxy類中定義了很多的方法,但根據上面動態代理的應用我們看到,最重要的一個方法就是newProxyInstance方法,該方法的作用就是動態創建一個代理類對象:

1 /** 2 * loader代表了委托類的類加載器 3 * interfaces代表了委托類的接口數組 4 * h代表委托類的實例 5 */ 6 @CallerSensitive 7 public static Object newProxyInstance(ClassLoader loader, 8 Class<?>[] interfaces, 9 InvocationHandler h) 10 throws IllegalArgumentException 11 { 12 // 判斷委托類實例是否為空,如果未空拋異常 13 Objects.requireNonNull(h); 14 15 final Class<?>[] intfs = interfaces.clone(); 16 final SecurityManager sm = System.getSecurityManager(); 17 if (sm != null) { 18 checkProxyAccess(Reflection.getCallerClass(), loader, intfs); 19 } 20 21 /* 22 * 獲取獲取代理類的Class實例 23 */ 24 Class<?> cl = getProxyClass0(loader, intfs); 25 26 /* 27 * Invoke its constructor with the designated invocation handler. 28 */ 29 try { 30 if (sm != null) { 31 checkNewProxyPermission(Reflection.getCallerClass(), cl); 32 } 33 34 //獲取代理類的Constructor對象 35 final Constructor<?> cons = cl.getConstructor(constructorParams); 36 final InvocationHandler ih = h; 37 if (!Modifier.isPublic(cl.getModifiers())) { 38 AccessController.doPrivileged(new PrivilegedAction<Void>() { 39 public Void run() { 40 cons.setAccessible(true); 41 return null; 42 } 43 }); 44 } 45 46 //利用反射原理中使用constructor動態創建動態代理類型 47 return cons.newInstance(new Object[]{h}); 48 } catch (IllegalAccessException|InstantiationException e) { 49 throw new InternalError(e.toString(), e); 50 } catch (InvocationTargetException e) { 51 Throwable t = e.getCause(); 52 if (t instanceof RuntimeException) { 53 throw (RuntimeException) t; 54 } else { 55 throw new InternalError(t.toString(), t); 56 } 57 } catch (NoSuchMethodException e) { 58 throw new InternalError(e.toString(), e); 59 } 60 } newProxyInstance

動態代理的應用場景

  動態代理最著名的應用場景就是spring中的aop

  

轉載于:https://www.cnblogs.com/qq455988971/p/8242946.html

總結

以上是生活随笔為你收集整理的java代理的原理及应用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。