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

Spring中AOP概念與兩種動態(tài)代理模式原理詳解

 更新時間:2021年10月24日 10:17:17   作者:HouFei-Liu  
AOP是面向切面編程的技術,AOP基于IoC基礎,是對OOP的有益補充,流行的AOP框架有Sping AOP、AspectJ,這篇文章主要給大家介紹了關于Spring中AOP概念與兩種動態(tài)代理模式原理的相關資料,需要的朋友可以參考下

1.概念

1.AOP技術簡介

AOP 為Aspect Oriented Programming 的縮寫,意思為面向切面編程,是通過預編譯方式和運行期動態(tài)代理實現(xiàn)程序功能的統(tǒng)一維護的一種技術。

AOP 是 OOP 的延續(xù),是軟件開發(fā)中的一個熱點,也是Spring框架中的一個重要內容,是函數(shù)式編程的一種衍生范型。利用AOP可以對業(yè)務邏輯的各個部分進行隔離,從而使得業(yè)務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發(fā)的效率。

2.AOP的優(yōu)勢

作用:在程序運行期間,在不修改源碼的情況下對方法進行功能增強優(yōu)勢:減少重復代碼,提高開發(fā)效率,并且便于維護

3.Spring AOP術語

Spring 的 AOP 實現(xiàn)底層就是對上面的動態(tài)代理的代碼進行了封裝,封裝后我們只需要對需要關注的部分進行代碼編寫,并通過配置的方式完成指定目標的方法增強。在正式講解 AOP 的操作之前,我們必須理解 AOP 的相關術語,常用的術語如下:

Target(目標對象):代理的目標對象Proxy (代理):一個類被 AOP 織入增強后,就產生一個結果代理類Joinpoint(連接點):所謂連接點是指那些被攔截到的點。在spring中,這些點指的是方法,因為spring只支持方法類型的連接點.(可能被增強的方法)Pointcut(切入點):所謂切入點是指我們要對哪些 Joinpoint 進行攔截的定義(被增強的方法)Advice(通知/ 增強):所謂通知是指攔截到 Joinpoint 之后所要做的事情就是通知(對目標對象增強的方法)Aspect(切面):是切入點和通知(引介)的結合(目標方法+增強=切面)Weaving(織入):是指把增強應用到目標對象來創(chuàng)建新的代理對象的過程。 spring采用動態(tài)代理織入,而AspectJ采用編譯期織入和類裝載期織入.(一個動作,切點和通知結合的過程=織入)

4.AOP 開發(fā)明確的事項

需要編寫的內容 編寫核心業(yè)務代碼(目標類的目標方法)編寫切面類,切面類中有通知(增強功能方法)在配置文件中,配置織入關系,即將哪些通知與哪些連接點進行結合 AOP 技術實現(xiàn)的內容 Spring 框架監(jiān)控切入點方法的執(zhí)行。一旦監(jiān)控到切入點方法被運行,使用代理機制,動態(tài)創(chuàng)建目標對象的代理對象,根據(jù)通知類別,在代理對象的對應位置,將通知對應的功能織入,完成完整的代碼邏輯運行。 AOP 底層使用哪種代理方式 在 spring 中,框架會根據(jù)目標類是否實現(xiàn)了接口來決定采用哪種動態(tài)代理的方式。

 2.AOP底層實現(xiàn)

實際上, AOP 的底層是通過 Spring 提供的的動態(tài)代理技術實現(xiàn)的。在運行期間, Spring通過動態(tài)代理技術動態(tài)的生成代理對象,代理對象方法執(zhí)行時進行增強功能的介入,在去調用目標對象的方法,從而完成功能的增強。

1.AOP 的動態(tài)代理技術:

常用的動態(tài)代理技術

  • JDK 代理 : 基于接口的動態(tài)代理技術
  • cglib 代理:基于父類的動態(tài)代理技術

2.基于jdk的動態(tài)代理代碼

//---------接口1------------
package com.itspring.proxy.jdk;

public interface TargetInterface1 {
    void save();
}


//---------接口2------------
package com.itspring.proxy.jdk;

public interface TargetInterface2 {
    void update();
}


//---------接口1,接口2實現(xiàn)類(目標類)------------
package com.itspring.proxy.jdk;

//目標類(被增強的類)
public class Target implements TargetInterface1 ,TargetInterface2{
    public void save() {
        System.out.println("save running...");
    }

    public void update() {
        System.out.println("update running...");
    }
}


//---------通知類(方法增強類)------------
package com.itspring.proxy.jdk;

//通知類(增強類)
public class Advice {

    public void before() {
        System.out.println("前置增強...");
    }

    public void afterRunning() {
        System.out.println("后置增強...");
    }
}


//---------測試代碼------------
package com.itspring.proxy.jdk;

import org.junit.Test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyTest {

    @Test
    public void test1() {

        final Target target = new Target();

        final Advice advice = new Advice();

        //返回值就是動態(tài)生成的代理對象
        TargetInterface1 proxy1 = (TargetInterface1) Proxy.newProxyInstance(
                target.getClass().getClassLoader(),  //目標類的類加載器
                target.getClass().getInterfaces(),  //目標類實現(xiàn)的接口(可能有多個)
                new InvocationHandler() {
                    //調用代理對象的任何方法,實質上都是調用invoke方法
                    public Object invoke(Object proxy,  //代理對象
                                         Method method,  //目標方法對象
                                         Object[] args  //目標方法的參數(shù)
                    ) throws Throwable {
                        System.out.println("正在執(zhí)行的方法:" + method.getName());
                        advice.before();  //前置增強
                        Object invoke = method.invoke(target, args);  //執(zhí)行目標方法
                        advice.afterRunning();  //后置增強
                        return invoke;
                    }
                }
        );

        proxy1.save();

        //返回值就是動態(tài)生成的代理對象
        TargetInterface2 proxy2 = (TargetInterface2) Proxy.newProxyInstance(
                target.getClass().getClassLoader(),  //目標類的類加載器
                target.getClass().getInterfaces(),  //目標類實現(xiàn)的接口(可能有多個)
                new InvocationHandler() {
                    //調用代理對象的任何方法,實質上都是調用invoke方法
                    public Object invoke(Object proxy,  //代理對象
                                         Method method,  //目標方法對象
                                         Object[] args  //目標方法的參數(shù)
                    ) throws Throwable {
                        System.out.println("正在執(zhí)行的方法:" + method.getName());
                        advice.before();
                        Object invoke = method.invoke(target, args);  //執(zhí)行目標方法
                        advice.afterRunning();
                        return invoke;
                    }
                }
        );

        proxy2.update();
    }
}


3.基于cglib的動態(tài)代理代碼

cglib是第三方的庫,spring集成了cglib.

//---------目標類-------------
package com.itspring.proxy.cglib;

import com.itspring.proxy.jdk.TargetInterface1;
import com.itspring.proxy.jdk.TargetInterface2;

//目標類(被增強的類)
public class Target {
    public void save() {
        System.out.println("save running...");
    }

    public void update() {
        System.out.println("update running...");
    }
}

//---------通知類(增強類)-------------
package com.itspring.proxy.cglib;

//通知類(增強類)
public class Advice {

    public void before() {
        System.out.println("前置增強...");
    }

    public void afterRunning() {
        System.out.println("后置增強...");
    }
}


//---------測試代碼-------------
package com.itspring.proxy.cglib;

import com.itspring.proxy.jdk.TargetInterface1;
import com.itspring.proxy.jdk.TargetInterface2;
import org.junit.Test;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyTest {

    @Test
    public void test1() {
        //目標對象
        final Target target = new Target();

        //增強對象
        final Advice advice = new Advice();

        //基于cglib生成動態(tài)代理對象
        //1.創(chuàng)建增強器
        Enhancer enhancer = new Enhancer();
        //2.創(chuàng)建父類
        enhancer.setSuperclass(Target.class);
        //3.設置回調
        enhancer.setCallback(new MethodInterceptor() {
            public Object intercept(Object proxy,  //代理對象
                                    Method method,  //目標方法
                                    Object[] objects,  //目標方法的參數(shù)
                                    MethodProxy methodProxy)  //目標方法的代理
                    throws Throwable {
                //前置增強
                advice.before();
                //目標方法
                Object invoke = method.invoke(target, objects);
                //后置增強
                advice.afterRunning();
                return invoke;
            }
        });
        //4.生成代理對象
        Target target1 = (Target) enhancer.create();
        //5.測試
        target1.save();
        target1.update();

    }
}


總結

到此這篇關于Spring中AOP概念與兩種動態(tài)代理模式原理的文章就介紹到這了,更多相關Spring動態(tài)代理模式原理內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 淺談myBatis中的插件機制

    淺談myBatis中的插件機制

    這篇文章主要介紹了淺談myBatis中的插件機制,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-11-11
  • 利用spring的攔截器自定義緩存的實現(xiàn)實例代碼

    利用spring的攔截器自定義緩存的實現(xiàn)實例代碼

    這篇文章主要介紹了利用spring的攔截器自定義緩存的實現(xiàn)實例代碼,分享了相關代碼示例,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下
    2018-02-02
  • SpringBoot中如何處理不同的類型的POST請求

    SpringBoot中如何處理不同的類型的POST請求

    在Web開發(fā)中,POST請求是非常常見的,用于向服務器提交數(shù)據(jù),根據(jù)數(shù)據(jù)的編碼方式,POST請求可以分為form-data、x-www-form-urlencoded和raw三種類型,本文將介紹這三種請求方式的區(qū)別,并展示如何在Spring Boot中編寫代碼來處理它們,需要的朋友可以參考下
    2024-08-08
  • 詳解Mybatis(五)Mapper接口

    詳解Mybatis(五)Mapper接口

    這篇文章主要介紹了Mybatis Mapper接口,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04
  • Java 實戰(zhàn)練手項目之醫(yī)院預約掛號系統(tǒng)的實現(xiàn)流程

    Java 實戰(zhàn)練手項目之醫(yī)院預約掛號系統(tǒng)的實現(xiàn)流程

    讀萬卷書不如行萬里路,只學書上的理論是遠遠不夠的,只有在實戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+SpringBoot+Maven+Vue+mysql實現(xiàn)一個醫(yī)院預約掛號系統(tǒng),大家可以在過程中查缺補漏,提升水平
    2021-11-11
  • MyBatis自定義映射關系和關聯(lián)查詢實現(xiàn)方法詳解

    MyBatis自定義映射關系和關聯(lián)查詢實現(xiàn)方法詳解

    這篇文章主要介紹了MyBatis自定義映射關系和關聯(lián)查詢實現(xiàn)方法,當POJO屬性名與數(shù)據(jù)庫列名不一致時,需要自定義實體類和結果集的映射關系,在MyBatis注解開發(fā)中,使用@Results定義并使用自定義映射,使用 @ResultMap使用自定義映射
    2023-04-04
  • Java IO流之原理分類與節(jié)點流文件操作詳解

    Java IO流之原理分類與節(jié)點流文件操作詳解

    流(Stream)是指一連串的數(shù)據(jù)(字符或字節(jié)),是以先進先出的方式發(fā)送信息的通道,數(shù)據(jù)源發(fā)送的數(shù)據(jù)經過這個通道到達目的地,按流向區(qū)分為輸入流和輸出流
    2021-10-10
  • Java中調用第三方接口的詳細代碼示例

    Java中調用第三方接口的詳細代碼示例

    這篇文章主要介紹了Java中調用第三方接口的詳細代碼示例,文章總結了多種Java進行HTTP請求的方法,每種方法都有其特點和適用場景,從原生到封裝,再到聲明式客戶端,滿足了不同復雜度的HTTP請求需求,需要的朋友可以參考下
    2024-12-12
  • Hibernate連接三種數(shù)據(jù)庫的配置文件

    Hibernate連接三種數(shù)據(jù)庫的配置文件

    今天小編就為大家分享一篇關于Hibernate連接三種數(shù)據(jù)庫的配置文件,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • java 詳解類加載器的雙親委派及打破雙親委派

    java 詳解類加載器的雙親委派及打破雙親委派

    這篇文章主要介紹了java 詳解類加載器的雙親委派及打破雙親委派的相關資料,需要的朋友可以參考下
    2017-01-01

最新評論

新巴尔虎左旗| 崇信县| 清镇市| 灵璧县| 连云港市| 措美县| 曲麻莱县| 金湖县| 辽宁省| 儋州市| 彭阳县| 泸溪县| 贡山| 永兴县| 北安市| 吴堡县| 湛江市| 新津县| 建平县| 湾仔区| 华宁县| 枝江市| 织金县| 东乌珠穆沁旗| 吉安市| 平度市| 板桥市| 霞浦县| 萨嘎县| 密山市| 凤冈县| 巴林左旗| 江川县| 鄂伦春自治旗| 尼木县| 汾西县| 许昌市| 潼南县| 崇文区| 上栗县| 新宁县|