一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術(shù)及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Spring AOP里的靜態(tài)代理和動態(tài)代理用法詳解

Spring AOP里的靜態(tài)代理和動態(tài)代理用法詳解

2020-07-25 00:14陳彥斌 Java教程

這篇文章主要介紹了 Spring AOP里的靜態(tài)代理和動態(tài)代理用法詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

什么是代理?

  為某一個對象創(chuàng)建一個代理對象,程序不直接用原本的對象,而是由創(chuàng)建的代理對象來控制原對象,通過代理類這中間一層,能有效控制對委托類對象的直接訪問,也可以很好地隱藏和保護委托類對象,同時也為實施不同控制策略預留了空間

什么是靜態(tài)代理

  由程序創(chuàng)建或特定工具自動生成源代碼,在程序運行前,代理類的.class文件就已經(jīng)存在

  通過將目標類與代理類實現(xiàn)同一個接口,讓代理類持有真實類對象,然后在代理類方法中調(diào)用真實類方法,在調(diào)用真實類方法的前后添加我們所需要的功能擴展代碼來達到增強的目的。

優(yōu)點

  •   代理使客戶端不需要知道實現(xiàn)類是什么,怎么做,而客戶端只需知道代理即可
  •   方便增加功能,擴展業(yè)務邏輯

缺點

  •   代理類中常出現(xiàn)大量冗余的代碼,非常不利于擴展和維護
  •   如果接口增加一個方法,除了所有實現(xiàn)類需要實現(xiàn)這個方法外,所有代理類也需要實現(xiàn)此方法。增加了代碼維護的復雜度

案例演示

PayService.java(接口)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package net.cybclass.sp.proxy;
 
public interface PayService {
  /**
   * 支付回調(diào)
   * @param outTradeNo 訂單號
   * @return
   */
  String callback(String outTradeNo);
 
  /**
   * 下單
   * @param userId 用戶id
   * @param productId 產(chǎn)品id
   * @return
   */
  int save(int userId,int productId);
}

PayServiceImpl.java(接口實現(xiàn)類)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
package net.cybclass.sp.proxy;
 
public class PayServiceImpl implements PayService{
  public String callback(String outTradeNo) {
    System.out.println("目標類 PayServiceImpl 回調(diào) 方法 callback");
    return outTradeNo;
  }
 
  public int save(int userId, int productId) {
    System.out.println("目標類 PayServiceImpl 回調(diào) 方法 save");
    return productId;
  }
}

StaticProxyPayServiceImpl.java(接口實現(xiàn)類,靜態(tài)代理)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package net.cybclass.sp.proxy;
 
public class StaticProxyPayServiceImpl implements PayService{
  private PayService payService;
  public StaticProxyPayServiceImpl(PayService payService)
  {
    this.payService=payService;
  }
  public String callback(String outTradeNo) {
    System.out.println("StaticProxyPayServiceImpl callback begin");
    String result=payService.callback(outTradeNo);
    System.out.println("StaticProxyPayServiceImpl callback end");
    return result;
  }
 
  public int save(int userId, int productId) {
    System.out.println("StaticProxyPayServiceImpl save begin");
    int id = payService.save(userId, productId);
    System.out.println("StaticProxyPayServiceImpl save end");
    return id;
  }
}

演示

Spring AOP里的靜態(tài)代理和動態(tài)代理用法詳解

什么是動態(tài)代理

  在程序運行時,運用反射機制動態(tài)創(chuàng)建而成,無需手動編寫代碼

JDK動態(tài)代理

CGLIB動態(tài)代理(原理:是對指定的業(yè)務類生成一個子類,并覆蓋其中的業(yè)務方法來實現(xiàn)代理)

jdk動態(tài)代理演示

?
1
2
3
4
5
6
定義一個類,去實現(xiàn)InvocationHandler這個接口,并車從寫invoke方法
 
//Object proxy:被代理的對象
//Method method:要調(diào)用的方法
//Object[] args:方法調(diào)用時所需要參數(shù)
public Object invoke(Object proxy, Method method, Object[] args){}

PayService.java(接口)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package net.cybclass.sp.proxy;
 
public interface PayService {
  /**
   * 支付回調(diào)
   * @param outTradeNo 訂單號
   * @return
   */
  String callback(String outTradeNo);
 
  /**
   * 下單
   * @param userId 用戶id
   * @param productId 產(chǎn)品id
   * @return
   */
  int save(int userId,int productId);
}

PayServiceImpl.java(接口實現(xiàn)類)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
package net.cybclass.sp.proxy;
 
public class PayServiceImpl implements PayService{
  public String callback(String outTradeNo) {
    System.out.println("目標類 PayServiceImpl 回調(diào) 方法 callback");
    return outTradeNo;
  }
 
  public int save(int userId, int productId) {
    System.out.println("目標類 PayServiceImpl 回調(diào) 方法 save");
    return productId;
  }
}

JDKProxy.java(jdk動態(tài)代理類)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package net.cybclass.sp.proxy;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
 
public class JDKProxy implements InvocationHandler {
  //目標類
  private Object targetObject;
 
  /**
   * 獲取代理對象
   * @param targetObject 目標類
   * @return
   */
  public Object newProxyInstance(Object targetObject) {
    this.targetObject = targetObject;
    //綁定關(guān)系,也就是和具體的那個實現(xiàn)類關(guān)聯(lián)
    return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
        targetObject.getClass().getInterfaces(), this);
  }
 
  /**
   * JDK動態(tài)代理
   *
   * @param proxy 靜態(tài)代理對象
   * @param method 要調(diào)用的方法
   * @param args  方法調(diào)用時所需要參數(shù)
   * @return
   * @throws Throwable
   */
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    Object result = null;
    try {
      System.out.println("通過JDK動態(tài)代理調(diào)用"+method.getName()+",打印日志 begin");
      result = method.invoke(targetObject, args);
      System.out.println("通過JDK動態(tài)代理調(diào)用"+method.getName()+",打印日志 end");
    } catch (Exception ex) {
      ex.printStackTrace();
    }
    return result;
  }
}

Spring AOP里的靜態(tài)代理和動態(tài)代理用法詳解

CGLIB動態(tài)代理演示

PayService.java(接口)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package net.cybclass.sp.proxy;
 
public interface PayService {
  /**
   * 支付回調(diào)
   * @param outTradeNo 訂單號
   * @return
   */
  String callback(String outTradeNo);
 
  /**
   * 下單
   * @param userId 用戶id
   * @param productId 產(chǎn)品id
   * @return
   */
  int save(int userId,int productId);
}

PayServiceImpl.java(接口實現(xiàn)類)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
package net.cybclass.sp.proxy;
 
public class PayServiceImpl implements PayService{
  public String callback(String outTradeNo) {
    System.out.println("目標類 PayServiceImpl 回調(diào) 方法 callback");
    return outTradeNo;
  }
 
  public int save(int userId, int productId) {
    System.out.println("目標類 PayServiceImpl 回調(diào) 方法 save");
    return productId;
  }
}

CGLIBProxy.java(CGLIB動態(tài)代理類)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package net.cybclass.sp.proxy;
 
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
 
import java.lang.reflect.Method;
 
public class CGLIBProxy implements MethodInterceptor {
  //目標類
  private Object targetObject;
  //綁定關(guān)系
  public Object newProxyInstance(Object targetObject){
    this.targetObject=targetObject;
    Enhancer enhancer=new Enhancer();
    //設置代理類的父類(目標類)
    enhancer.setSuperclass(this.targetObject.getClass());
    //設置回調(diào)函數(shù)
    enhancer.setCallback(this);
    //創(chuàng)建子類(代理對象)
    return enhancer.create();
  }
  public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
    Object result=null;
    try
    {
      System.out.println("通過CGLIB動態(tài)代理調(diào)用"+method.getName()+",打印日志 begin");
      result=methodProxy.invokeSuper(o,args);
      System.out.println("通過CGLIB動態(tài)代理調(diào)用"+method.getName()+",打印日志 end");
    }
    catch (Exception ex){
      ex.printStackTrace();
    }
    return result;
  }
}

Spring AOP里的靜態(tài)代理和動態(tài)代理用法詳解

總結(jié)

  動態(tài)代理與靜態(tài)代理相比較,最大的好處是接口中聲明的所有方法都被轉(zhuǎn)移到調(diào)用處理器一個集中的方法中處理,解耦和易維護。

兩種動態(tài)代理的區(qū)別

  • JDK動態(tài)代理:要求目標對象實現(xiàn)一個接口,但是有時候目標對象只是一個單獨的對象,并沒有實現(xiàn)任何的接口,這個時候就可以用CGLIB動態(tài)代理
  • JDK動態(tài)代理是自帶的,CGLIB需要引入第三方包
  • CGLIB動態(tài)代理,它是內(nèi)存中構(gòu)建一個子類對象從而實現(xiàn)對目標對象功能的擴展
  • CGLIB動態(tài)代理基于繼承來實現(xiàn)代理,所以無法對final類,private方法和static方法實現(xiàn)代理

Spring AOP中的代理使用的默認策略

  • 如果目標對象實現(xiàn)類接口,則默認采用JDK動態(tài)代理
  • 如果目標對象沒有實現(xiàn)接口,則采用CGLIB進行動態(tài)代理

到此這篇關(guān)于 Spring AOP里的靜態(tài)代理和動態(tài)代理用法詳解的文章就介紹到這了,更多相關(guān) Spring AOP 靜態(tài)代理 動態(tài)代理內(nèi)容請搜索服務器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務器之家!

原文鏈接:https://www.cnblogs.com/chenyanbin/p/13306055.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日日插插 | 激情婷婷成人亚洲综合 | 日韩精品视频美在线精品视频 | 亚洲日韩精品欧美一区二区一 | 国产自拍视频网站 | 国产精品亚洲片在线观看麻豆 | 九九久久国产精品大片 | 男人女人叉叉叉 | 日韩国产成人精品视频人 | 国产91区| 欧美人与日本人xx在线视频 | 免费一级毛片在线播放 | 久久学生精品国产自在拍 | 亚洲精品视频专区 | 色色色色色色网 | 四虎在线最新地址公告 | 国产第2页| 鸥美毛片| 欧美日韩中文国产一区二区三区 | 毛片网站大全 | 国产免费专区 | 小莹的性荡生活45章 | 精品久久久久久亚洲精品 | 日本68xxxxxxxxx59 日本 视频 在线 | 单亲乱l仑在线观看免费观看 | 9久热久爱免费精品视频在线观看 | 波多野结衣教师未删减版 | 欧美草比视频 | tubehdxx丝袜正片 | 亚洲酒色1314狠狠做 | 日本制服丝袜 | 日韩色图区 | 香艳69xxxxx有声小说 | 91九色国产porny | 青草福利视频 | 被黑人同学彻底征服全文小说阅读 | 青草香蕉精品视频在线观看 | 北岛玲在线视频 | 美女班主任下面好爽好湿好紧 | 美琪美腿白丝交小说 | kayden·kross hd在线|