欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時間:2020年07月24日 16:36:23   作者:陳彥斌  
這篇文章主要介紹了 Spring AOP里的靜態(tài)代理和動態(tài)代理用法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

什么是代理?

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

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

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

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

優(yōu)點

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

缺點

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

案例演示

PayService.java(接口)

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)類)

package net.cybclass.sp.proxy;

public class PayServiceImpl implements PayService{
 public String callback(String outTradeNo) {
  System.out.println("目標(biāo)類 PayServiceImpl 回調(diào) 方法 callback");
  return outTradeNo;
 }

 public int save(int userId, int productId) {
  System.out.println("目標(biāo)類 PayServiceImpl 回調(diào) 方法 save");
  return productId;
 }
}

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

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;
 }
}

演示

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

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

JDK動態(tài)代理

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

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

定義一個類,去實現(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(接口)

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)類)

package net.cybclass.sp.proxy;

public class PayServiceImpl implements PayService{
 public String callback(String outTradeNo) {
  System.out.println("目標(biāo)類 PayServiceImpl 回調(diào) 方法 callback");
  return outTradeNo;
 }

 public int save(int userId, int productId) {
  System.out.println("目標(biāo)類 PayServiceImpl 回調(diào) 方法 save");
  return productId;
 }
}

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

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 {
 //目標(biāo)類
 private Object targetObject;

 /**
  * 獲取代理對象
  * @param targetObject 目標(biāo)類
  * @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;
 }
}

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

PayService.java(接口)

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)類)

package net.cybclass.sp.proxy;

public class PayServiceImpl implements PayService{
 public String callback(String outTradeNo) {
  System.out.println("目標(biāo)類 PayServiceImpl 回調(diào) 方法 callback");
  return outTradeNo;
 }

 public int save(int userId, int productId) {
  System.out.println("目標(biāo)類 PayServiceImpl 回調(diào) 方法 save");
  return productId;
 }
}

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

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 {
 //目標(biāo)類
 private Object targetObject;
 //綁定關(guān)系
 public Object newProxyInstance(Object targetObject){
  this.targetObject=targetObject;
  Enhancer enhancer=new Enhancer();
  //設(shè)置代理類的父類(目標(biāo)類)
  enhancer.setSuperclass(this.targetObject.getClass());
  //設(shè)置回調(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;
 }
}

總結(jié)

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

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

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

Spring AOP中的代理使用的默認(rèn)策略

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

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

相關(guān)文章

  • 一文搞懂Java常見的三種代理模式(靜態(tài)代理、動態(tài)代理和cglib代理)

    一文搞懂Java常見的三種代理模式(靜態(tài)代理、動態(tài)代理和cglib代理)

    Java中常見的三種代理模式是靜態(tài)代理模式、動態(tài)代理模式和CGLIB代理模式,本文就來給大家詳細(xì)的講解一下這三種代理模式,感興趣的小伙伴跟著小編一起來看看吧
    2023-08-08
  • 關(guān)于Spring?Ioc和DI注解的問題

    關(guān)于Spring?Ioc和DI注解的問題

    這篇文章主要介紹了Spring?Ioc和DI注解,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • JAVA實現(xiàn)較完善的布隆過濾器的示例代碼

    JAVA實現(xiàn)較完善的布隆過濾器的示例代碼

    這篇文章主要介紹了JAVA實現(xiàn)較完善的布隆過濾器的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-10-10
  • SpringBoot Actuator未授權(quán)訪問漏洞修復(fù)詳解

    SpringBoot Actuator未授權(quán)訪問漏洞修復(fù)詳解

    這篇文章主要介紹了SpringBoot Actuator未授權(quán)訪問漏洞修復(fù)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Java實現(xiàn)單人信息管理程序

    Java實現(xiàn)單人信息管理程序

    這篇文章主要為大家詳細(xì)介紹了Java實現(xiàn)單人信息管理程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • SpringBoot使用ExceptionHandler做異常處理

    SpringBoot使用ExceptionHandler做異常處理

    這篇文章主要介紹了SpringBoot使用ExceptionHandler做異常處理,這篇文章通過多種方法案例來介紹該項技術(shù)的使用,需要的朋友可以參考下
    2021-06-06
  • Spring MVC之WebApplicationContext_動力節(jié)點Java學(xué)院整理

    Spring MVC之WebApplicationContext_動力節(jié)點Java學(xué)院整理

    這篇文章主要介紹了Spring MVC之WebApplicationContext的相關(guān)資料,需要的朋友可以參考下
    2017-08-08
  • 用Java生成二維碼并附帶文字信息

    用Java生成二維碼并附帶文字信息

    這篇文章主要介紹了用Java生成二維碼并附帶文字信息,文中有非常詳細(xì)的代碼示例,對正在學(xué)習(xí)java的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • 一文詳解Java對象的序列化和反序列化

    一文詳解Java對象的序列化和反序列化

    本文主要介紹了一文詳解Java對象的序列化和反序列化,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • Java鎖之可重入鎖介紹

    Java鎖之可重入鎖介紹

    這篇文章主要介紹了Java鎖之可重入鎖介紹,可重入鎖,也叫做遞歸鎖,指的是同一線程外層函數(shù)獲得鎖之后,內(nèi)層遞歸函數(shù)仍然有獲取該鎖的代碼,但不受影響,需要的朋友可以參考下
    2014-11-11

最新評論