最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

什么是代理?

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

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

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

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

優(yōu)點(diǎn)

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

缺點(diǎn)

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

案例演示

PayService.java(接口)

package net.cybclass.sp.proxy;

public interface PayService {
 /**
  * 支付回調(diào)
  * @param outTradeNo 訂單號(hào)
  * @return
  */
 String callback(String outTradeNo);

 /**
  * 下單
  * @param userId 用戶(hù)id
  * @param productId 產(chǎn)品id
  * @return
  */
 int save(int userId,int productId);
}

PayServiceImpl.java(接口實(shí)現(xiàn)類(lèi))

package net.cybclass.sp.proxy;

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

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

StaticProxyPayServiceImpl.java(接口實(shí)現(xiàn)類(lèi),靜態(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;
 }
}

演示

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

  在程序運(yùn)行時(shí),運(yùn)用反射機(jī)制動(dòng)態(tài)創(chuàng)建而成,無(wú)需手動(dòng)編寫(xiě)代碼

JDK動(dòng)態(tài)代理

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

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

定義一個(gè)類(lèi),去實(shí)現(xiàn)InvocationHandler這個(gè)接口,并車(chē)從寫(xiě)invoke方法

//Object proxy:被代理的對(duì)象
//Method method:要調(diào)用的方法
//Object[] args:方法調(diào)用時(shí)所需要參數(shù)
public Object invoke(Object proxy, Method method, Object[] args){}

PayService.java(接口)

package net.cybclass.sp.proxy;

public interface PayService {
 /**
  * 支付回調(diào)
  * @param outTradeNo 訂單號(hào)
  * @return
  */
 String callback(String outTradeNo);

 /**
  * 下單
  * @param userId 用戶(hù)id
  * @param productId 產(chǎn)品id
  * @return
  */
 int save(int userId,int productId);
}

PayServiceImpl.java(接口實(shí)現(xiàn)類(lèi))

package net.cybclass.sp.proxy;

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

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

JDKProxy.java(jdk動(dòng)態(tài)代理類(lè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)類(lèi)
 private Object targetObject;

 /**
  * 獲取代理對(duì)象
  * @param targetObject 目標(biāo)類(lèi)
  * @return
  */
 public Object newProxyInstance(Object targetObject) {
  this.targetObject = targetObject;
  //綁定關(guān)系,也就是和具體的那個(gè)實(shí)現(xiàn)類(lèi)關(guān)聯(lián)
  return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
    targetObject.getClass().getInterfaces(), this);
 }

 /**
  * JDK動(dòng)態(tài)代理
  *
  * @param proxy 靜態(tài)代理對(duì)象
  * @param method 要調(diào)用的方法
  * @param args 方法調(diào)用時(shí)所需要參數(shù)
  * @return
  * @throws Throwable
  */
 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  Object result = null;
  try {
   System.out.println("通過(guò)JDK動(dòng)態(tài)代理調(diào)用"+method.getName()+",打印日志 begin");
   result = method.invoke(targetObject, args);
   System.out.println("通過(guò)JDK動(dòng)態(tài)代理調(diào)用"+method.getName()+",打印日志 end");
  } catch (Exception ex) {
   ex.printStackTrace();
  }
  return result;
 }
}

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

PayService.java(接口)

package net.cybclass.sp.proxy;

public interface PayService {
 /**
  * 支付回調(diào)
  * @param outTradeNo 訂單號(hào)
  * @return
  */
 String callback(String outTradeNo);

 /**
  * 下單
  * @param userId 用戶(hù)id
  * @param productId 產(chǎn)品id
  * @return
  */
 int save(int userId,int productId);
}

PayServiceImpl.java(接口實(shí)現(xiàn)類(lèi))

package net.cybclass.sp.proxy;

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

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

CGLIBProxy.java(CGLIB動(dòng)態(tài)代理類(lè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)類(lèi)
 private Object targetObject;
 //綁定關(guān)系
 public Object newProxyInstance(Object targetObject){
  this.targetObject=targetObject;
  Enhancer enhancer=new Enhancer();
  //設(shè)置代理類(lèi)的父類(lèi)(目標(biāo)類(lèi))
  enhancer.setSuperclass(this.targetObject.getClass());
  //設(shè)置回調(diào)函數(shù)
  enhancer.setCallback(this);
  //創(chuàng)建子類(lèi)(代理對(duì)象)
  return enhancer.create();
 }
 public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
  Object result=null;
  try
  {
   System.out.println("通過(guò)CGLIB動(dòng)態(tài)代理調(diào)用"+method.getName()+",打印日志 begin");
   result=methodProxy.invokeSuper(o,args);
   System.out.println("通過(guò)CGLIB動(dòng)態(tài)代理調(diào)用"+method.getName()+",打印日志 end");
  }
  catch (Exception ex){
   ex.printStackTrace();
  }
  return result;
 }
}

總結(jié)

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

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

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

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

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

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

相關(guān)文章

  • java 方法重寫(xiě)與權(quán)限修飾符以及多態(tài)和抽象類(lèi)詳解概念和用法

    java 方法重寫(xiě)與權(quán)限修飾符以及多態(tài)和抽象類(lèi)詳解概念和用法

    重寫(xiě)是子類(lèi)對(duì)父類(lèi)的允許訪問(wèn)的方法的實(shí)現(xiàn)過(guò)程進(jìn)行重新編寫(xiě), 返回值和形參都不能改變。即外殼不變,核心重寫(xiě),權(quán)限修飾符用于控制被修飾變量、方法、類(lèi)的可見(jiàn)范圍,說(shuō)明了面向?qū)ο蟮姆庋b性,所以我們要適用他們盡可能的讓權(quán)限降到最低,從而安全性提高
    2021-10-10
  • Spring事務(wù)@Transactional注解四種不生效案例場(chǎng)景分析

    Spring事務(wù)@Transactional注解四種不生效案例場(chǎng)景分析

    這篇文章主要為大家介紹了Spring事務(wù)@Transactional注解四種不生效的案例場(chǎng)景示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • Java操作itextpdf實(shí)現(xiàn)PDF添加文字,圖片和簽名

    Java操作itextpdf實(shí)現(xiàn)PDF添加文字,圖片和簽名

    這篇文章主要為大家詳細(xì)介紹了Java如何操作itextpdf實(shí)現(xiàn)PDF添加文字,圖片和簽名等功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以參考一下
    2025-01-01
  • spring boot 使用profile來(lái)分區(qū)配置的操作

    spring boot 使用profile來(lái)分區(qū)配置的操作

    這篇文章主要介紹了spring boot使用profile來(lái)分區(qū)配置的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 在maven工程里運(yùn)行java main方法

    在maven工程里運(yùn)行java main方法

    這篇文章主要介紹了在maven工程里運(yùn)行java main方法,需要的朋友可以參考下
    2014-04-04
  • Java中BitMap(位圖)hutool版、IntMap、LongMap示例詳解

    Java中BitMap(位圖)hutool版、IntMap、LongMap示例詳解

    這篇文章主要給大家介紹了關(guān)于Java中BitMap(位圖)hutool版、IntMap、LongMap的相關(guān)資料,通過(guò)位運(yùn)算高效存儲(chǔ)和檢索整數(shù),相比于傳統(tǒng)數(shù)組,它們?cè)趦?nèi)存占用和性能上都有顯著優(yōu)勢(shì),需要的朋友可以參考下
    2024-12-12
  • Java執(zhí)行JS腳本工具

    Java執(zhí)行JS腳本工具

    今天小編就為大家分享一篇關(guān)于Java執(zhí)行JS腳本工具,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-12-12
  • SpringBoot實(shí)現(xiàn)其他普通類(lèi)調(diào)用Spring管理的Service,dao等bean

    SpringBoot實(shí)現(xiàn)其他普通類(lèi)調(diào)用Spring管理的Service,dao等bean

    這篇文章主要介紹了SpringBoot實(shí)現(xiàn)其他普通類(lèi)調(diào)用Spring管理的Service,dao等bean,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • java8中的lambda表達(dá)式,看這篇絕對(duì)夠

    java8中的lambda表達(dá)式,看這篇絕對(duì)夠

    這篇文章主要介紹了java8中的lambda表達(dá)式,看這篇絕對(duì)夠!具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Spring?Boot項(xiàng)目如何使用Maven打包并帶上依賴(lài)

    Spring?Boot項(xiàng)目如何使用Maven打包并帶上依賴(lài)

    在這篇博客中,介紹如何使用Maven將Spring?Boot項(xiàng)目及其依賴(lài)項(xiàng)打包成一個(gè)可執(zhí)行的jar文件。我們將使用Spring?Boot的spring-boot-maven-plugin插件來(lái)完成這個(gè)任務(wù),感興趣的朋友跟隨小編一起看看吧
    2023-06-06

最新評(píng)論

右玉县| 古田县| 通河县| 新乐市| 海林市| 泾阳县| 巢湖市| 泰顺县| 蚌埠市| 宁波市| 寿宁县| 舒兰市| 故城县| 仙居县| 喀喇沁旗| 上蔡县| 环江| 邵东县| 常山县| 甘谷县| 子长县| 格尔木市| 巩留县| 富平县| 当阳市| 大悟县| 黑山县| 浪卡子县| 类乌齐县| 玉门市| 达孜县| 南昌县| 江达县| 长丰县| 梓潼县| 保靖县| 合江县| 文水县| 丁青县| 开阳县| 长垣县|