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

服務器之家:專注于服務器技術(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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 果冻传媒天美传媒网址入口 | 无限资源在线观看播放 | 亚洲国产第一区二区香蕉日日 | 3x免费高清视频 | 四虎comwww最新地址 | se01在线看片| 男人和女人日 | 娇女的呻吟亲女禁忌h16 | 国产欧美日韩在线观看精品 | 无码一区国产欧美在线资源 | yellow字幕网在线zmzz91 | 美女靠逼动漫 | 草莓视频在线免费观看 | 欧美大屁屁| 久久AV国产麻豆HD真实 | 日本噜噜影院 | 精品久久99麻豆蜜桃666 | 亚洲理论视频 | 美女天天操 | www.一区二区三区.com | 国产美女屁股直流白浆视频无遮挡 | 国产首页精品 | 国产精品久久现线拍久青草 | 手机看片自拍 | 日韩一级免费毛片 | 欧美一区二区不卡视频 | 明星ai人脸替换造梦在线播放 | 香蕉久草在线 | avtt天堂在线 | 天堂a视频 | 石原莉奈adn093店长未婚妻 | 我半夜摸妺妺的奶C了她软件 | 成年人视频在线免费看 | 日本三级欧美三级人妇英文 | 欧美成人二区 | h玉足嫩脚嗯啊白丝 | ipx 在线播放 | 好湿好紧好多水c | 电车痴汉中文字幕 | 精品高潮呻吟99AV无码视频 | 亚洲精品国产一区二区第一页 |