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

Spring AOP的底層實(shí)現(xiàn)方式-代理模式

 更新時(shí)間:2021年11月24日 15:14:01   作者:AlphaBINGOD  
這篇文章主要介紹了Spring AOP的底層實(shí)現(xiàn)方式-代理模式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

在學(xué)習(xí)Spring的過程中,留下一下痕跡。

代理模式,其實(shí)就是讓別人做同樣的事情,但是別人卻不僅將我的事情做了,還會(huì)把他的事情也做了,換言之,這個(gè)人做的事情,是他獨(dú)有的事情和我需要做的事情的綜合?;氐酱a,那么就是,代理類執(zhí)行與委托類同樣的方法,在這方法里代理類不僅可以執(zhí)行委托類的方法的內(nèi)容,還可以添加自己的另外的內(nèi)容,在使用代理類的時(shí)候,會(huì)比直接使用委托類具有更多的能力,所以我們會(huì)直接使用代理類。

通常,代理類雖然具備更多的能力,但是代理類更多的能力其實(shí)是比較固定的。

例如,在JDBC里,或在ORM框架里,都會(huì)存在事務(wù)的開啟和提交,如果我們直接將事務(wù)代碼和業(yè)務(wù)代碼寫在一起,其實(shí)也是可以的,不過,這樣做會(huì)使得每一個(gè)需要事務(wù)的方法,都要添加事務(wù)代碼,造成代碼的分散冗余,那么,針對(duì)這種情況,我們希望業(yè)務(wù)代碼可以抽離出來,每一個(gè)業(yè)務(wù)方法都只寫業(yè)務(wù)內(nèi)容,同時(shí)我們又希望,在執(zhí)行業(yè)務(wù)方法時(shí),可以有一種方式自動(dòng)添加業(yè)務(wù)代碼,這種需求,其實(shí)就是有了代理的需求,因?yàn)槲覀兿M€是使用原來的方法,但是出來的效果希望是多出事務(wù)代碼,也就是希望業(yè)務(wù)代碼得到增強(qiáng)??梢赃@樣理解了,抽離出來的業(yè)務(wù)代碼,是一個(gè)委托類,而可以將委托類自動(dòng)增強(qiáng)并添加事務(wù)代碼的代碼,是一個(gè)代理類,它代理執(zhí)行委托類,具備了委托類原有的業(yè)務(wù)能力之余,增加了事務(wù)處理的代碼。

我理解的代理模式,其實(shí)就是將委托類融入到代理類里,換句話說,代理類也就是委托類的擴(kuò)充而已。

還有不僅是spring 的AOP是代理模式,還有Struts2的攔截器實(shí)現(xiàn)也是基于動(dòng)態(tài)代理的,動(dòng)態(tài)代理是一種很常見也很重要的設(shè)計(jì)模式。

說了很多,那么如何實(shí)現(xiàn)代理,那我們先說說靜態(tài)代理。

1.1 靜態(tài)代理

一個(gè)接口,兩個(gè)實(shí)現(xiàn)類,代理實(shí)現(xiàn)類組合真實(shí)實(shí)現(xiàn)類

靜態(tài)代理,是一種根據(jù)上面的理論,很自然會(huì)想到的一種不依賴于其他技術(shù)的代理模式實(shí)現(xiàn)方式。而他的實(shí)現(xiàn)過程如下圖。

這里寫圖片描述

如果使用過靜態(tài)代理,那么很容易理解,靜態(tài)代理存在的缺陷。

因此,也就出現(xiàn)了動(dòng)態(tài)代理。

動(dòng)態(tài)代理的動(dòng)態(tài), 就是可以動(dòng)態(tài)的切換真實(shí)實(shí)現(xiàn)類, 也就是說可以一個(gè)代理類(相同的代碼, 相同的增強(qiáng)操作)應(yīng)對(duì)一堆不確定的真實(shí)實(shí)現(xiàn)類.

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

JDK動(dòng)態(tài)代理和CGlib字節(jié)碼動(dòng)態(tài)代理

1.2.1 JDK動(dòng)態(tài)代理(必須有接口)

通過java.lang.reflect.Proxy類實(shí)現(xiàn)。

動(dòng)態(tài)代理就是為了解決靜態(tài)代理不靈活的缺陷而產(chǎn)生的。靜態(tài)代理是固定的,一旦確定了代碼,如果委托類新增一個(gè)方法,而這個(gè)方法又需要增強(qiáng),那么就必須在代理類里重寫一個(gè)帶增強(qiáng)的方法。而動(dòng)態(tài)代理可以靈活替換代理方法,動(dòng)態(tài)就是體現(xiàn)在這里。

這里寫圖片描述

public interface TargetClass {
    void sayHello();
}
public class TargetClassImpl implements TargetClass{
    public void sayHello() {
        System.out.println("你好");
    }
}
public class JdkProxy implements InvocationHandler {
    private TargetClass targetClass;
    public Object createProxy(TargetClass targetClass){
        //傳入真實(shí)實(shí)現(xiàn)類, 本身要做的事情會(huì)由他自己做, 代理類會(huì)額外進(jìn)行其他增強(qiáng)操作
        this.targetClass = targetClass; 
        //獲取本類類加載器
        ClassLoader classLoader = JdkProxy.class.getClassLoader();
        ///獲取被代理對(duì)象的所有接口
        Class[] clazz = targetClass.getClass().getInterfaces();
        System.out.println(clazz.length);
        //生成代理類并返回
        return Proxy.newProxyInstance(classLoader, clazz, this);
    }
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("JDKProxy前置增強(qiáng)");
        Object obj = method.invoke(targetClass,args);
        System.out.println("JDKProxy后置增強(qiáng)");
        return obj;
    }
}
public class Test {
    public static void main(String[] args) {
		JdkProxy jdkProxy = new JdkProxy();
		TargetClass targetClass = new TargetClassImpl();
		TargetClass targetClass1 = (TargetClass) jdkProxy.createProxy(targetClass);
		targetClass1.sayHello();
}

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

(不需要類繼承任何接口,字節(jié)碼技術(shù))

CGlib包在Spring core包里。

這里寫圖片描述

public class CGlibTaretClass {
    public void sayHello(){
        System.out.println("我是CGlib,我不需要接口");
    }
}
package CGlibProxyTest;
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{
    //代理方法
    public Object createProxy(Object target){
        //創(chuàng)建一個(gè)動(dòng)態(tài)類對(duì)象
        Enhancer enhancer = new Enhancer();
        //確定要增強(qiáng)的類,設(shè)置期父類
        enhancer.setSuperclass(target.getClass());
        //添加回調(diào)函數(shù)
        enhancer.setCallback(this);
        //返回創(chuàng)建的代理類
        return enhancer.create();
    }
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("CGlib前置增強(qiáng)");
        Object obj = methodProxy.invokeSuper(o,objects);
        System.out.println("CGlib后置增強(qiáng)");
        return obj;
    }
}
public class Test {
    public static void main(String[] args) {
		CGlibProxy cGlibProxy = new CGlibProxy();
        CGlibTaretClass cGlibTaretClass = new CGlibTaretClass();
        CGlibTaretClass cGlibTaretClass1 = (CGlibTaretClass)cGlibProxy.createProxy(cGlibTaretClass);
        cGlibTaretClass1.sayHello();
   }

最后:代理模式解決的是常見的代碼組織問題,它并不神秘,不要被他的名字嚇倒。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • java微信企業(yè)號(hào)開發(fā)之通訊錄

    java微信企業(yè)號(hào)開發(fā)之通訊錄

    這篇文章主要為大家詳細(xì)介紹了java微信企業(yè)號(hào)開發(fā)之通訊錄的相關(guān)資料,感興趣的小伙伴們可以參考一下
    2016-06-06
  • Java設(shè)計(jì)模式之淺談外觀模式

    Java設(shè)計(jì)模式之淺談外觀模式

    這篇文章主要介紹了Java設(shè)計(jì)模式之外觀模式的相關(guān)資料,需要的朋友可以參考下
    2022-09-09
  • Maven引用自定義jar包方式

    Maven引用自定義jar包方式

    這篇文章主要介紹了Maven引用自定義jar包方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java上傳下載文件并實(shí)現(xiàn)加密解密

    Java上傳下載文件并實(shí)現(xiàn)加密解密

    這篇文章主要介紹了Java上傳下載文件并實(shí)現(xiàn)加密解密,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Spring Cloud超詳細(xì)i講解Feign自定義配置與使用

    Spring Cloud超詳細(xì)i講解Feign自定義配置與使用

    這篇文章主要介紹了SpringCloud Feign自定義配置與使用,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • servlet創(chuàng)建web后端程序的示例代碼

    servlet創(chuàng)建web后端程序的示例代碼

    本文主要介紹了servlet創(chuàng)建web后端程序的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • SpringBoot?整合Security權(quán)限控制的初步配置

    SpringBoot?整合Security權(quán)限控制的初步配置

    這篇文章主要為大家介紹了SpringBoot?整合Security權(quán)限控制的初步配置實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • mybatis plus 開啟sql日志打印的方法小結(jié)

    mybatis plus 開啟sql日志打印的方法小結(jié)

    Mybatis-Plus(簡(jiǎn)稱MP)是一個(gè) Mybatis 的增強(qiáng)工具,在 Mybatis 的基礎(chǔ)上只做增強(qiáng)不做改變,為簡(jiǎn)化開發(fā)、提高效率而生。本文重點(diǎn)給大家介紹mybatis plus 開啟sql日志打印的方法小結(jié),感興趣的朋友一起看看吧
    2021-09-09
  • Spring的@ConfigurationProperties注解詳解

    Spring的@ConfigurationProperties注解詳解

    這篇文章主要介紹了Spring的@ConfigurationProperties注解詳解,@ConfigurationProperties該注解是用來獲取yml或者properties配置文件的配置信息,下面根據(jù)一些配置信息給出案例代碼進(jìn)行講解,需要的朋友可以參考下
    2023-11-11
  • Javax Validation自定義注解進(jìn)行身份證號(hào)校驗(yàn)

    Javax Validation自定義注解進(jìn)行身份證號(hào)校驗(yàn)

    這篇文章主要為大家詳細(xì)介紹了如何通過Javax Validation自定義注解進(jìn)行身份證號(hào)校驗(yàn),文中的示例代碼講解詳細(xì),有需要的小伙伴可以參考一下
    2024-10-10

最新評(píng)論

七台河市| 白城市| 满城县| 德昌县| 肇庆市| 柯坪县| 辰溪县| 凤翔县| 扶余县| 新宾| 鄂托克前旗| 平凉市| 建平县| 屏南县| 峡江县| 沈丘县| 福安市| 淄博市| 玉田县| 锡林郭勒盟| 甘孜县| 色达县| 栖霞市| 满城县| 文昌市| 宁海县| 威海市| 中阳县| 察隅县| 中山市| 昌乐县| 花莲市| 昭平县| 扬中市| 三台县| 西藏| 田林县| 澜沧| 通江县| 合肥市| 同德县|