亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

1.概念

1.AOP技術(shù)簡(jiǎn)介

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

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

2.AOP的優(yōu)勢(shì)

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

3.Spring AOP術(shù)語(yǔ)

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

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

4.AOP 開(kāi)發(fā)明確的事項(xiàng)

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

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

實(shí)際上, AOP 的底層是通過(guò) Spring 提供的的動(dòng)態(tài)代理技術(shù)實(shí)現(xiàn)的。在運(yùn)行期間, Spring通過(guò)動(dòng)態(tài)代理技術(shù)動(dòng)態(tài)的生成代理對(duì)象,代理對(duì)象方法執(zhí)行時(shí)進(jìn)行增強(qiáng)功能的介入,在去調(diào)用目標(biāo)對(duì)象的方法,從而完成功能的增強(qiáng)。

1.AOP 的動(dòng)態(tài)代理技術(shù):

常用的動(dòng)態(tài)代理技術(shù)

  • JDK 代理 : 基于接口的動(dòng)態(tài)代理技術(shù)
  • cglib 代理:基于父類(lèi)的動(dòng)態(tài)代理技術(shù)

2.基于jdk的動(dòng)態(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實(shí)現(xiàn)類(lèi)(目標(biāo)類(lèi))------------
package com.itspring.proxy.jdk;

//目標(biāo)類(lèi)(被增強(qiáng)的類(lèi))
public class Target implements TargetInterface1 ,TargetInterface2{
    public void save() {
        System.out.println("save running...");
    }

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


//---------通知類(lèi)(方法增強(qiáng)類(lèi))------------
package com.itspring.proxy.jdk;

//通知類(lèi)(增強(qiáng)類(lèi))
public class Advice {

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

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


//---------測(cè)試代碼------------
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();

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

        proxy1.save();

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

        proxy2.update();
    }
}


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

cglib是第三方的庫(kù),spring集成了cglib.

//---------目標(biāo)類(lèi)-------------
package com.itspring.proxy.cglib;

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

//目標(biāo)類(lèi)(被增強(qiáng)的類(lèi))
public class Target {
    public void save() {
        System.out.println("save running...");
    }

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

//---------通知類(lèi)(增強(qiáng)類(lèi))-------------
package com.itspring.proxy.cglib;

//通知類(lèi)(增強(qiáng)類(lèi))
public class Advice {

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

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


//---------測(cè)試代碼-------------
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() {
        //目標(biāo)對(duì)象
        final Target target = new Target();

        //增強(qiáng)對(duì)象
        final Advice advice = new Advice();

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

    }
}


總結(jié)

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

相關(guān)文章

  • Java兩種方法計(jì)算出階乘尾部連續(xù)0的個(gè)數(shù)

    Java兩種方法計(jì)算出階乘尾部連續(xù)0的個(gè)數(shù)

    這篇文章主要介紹了Java兩種方法計(jì)算出階乘尾部連續(xù)0的個(gè)數(shù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • 用Eclipse生成JPA元模型的方法

    用Eclipse生成JPA元模型的方法

    下面小編就為大家?guī)?lái)一篇用Eclipse生成JPA元模型的方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • SpringMVC整合SSM實(shí)現(xiàn)表現(xiàn)層數(shù)據(jù)封裝詳解

    SpringMVC整合SSM實(shí)現(xiàn)表現(xiàn)層數(shù)據(jù)封裝詳解

    這篇文章主要介紹了SpringMVC整合SSM實(shí)現(xiàn)表現(xiàn)層數(shù)據(jù)封裝,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2022-10-10
  • Spring Boot統(tǒng)一異常處理最佳實(shí)踐(拓展篇)

    Spring Boot統(tǒng)一異常處理最佳實(shí)踐(拓展篇)

    這篇文章主要給大家介紹了關(guān)于Spring Boot統(tǒng)一異常處理最佳實(shí)踐(拓展篇)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • 詳解MyBatis的SqlSession獲取流程

    詳解MyBatis的SqlSession獲取流程

    SqlSession的獲取是通過(guò)SqlSessionFactory的openSession() 方法,那么具體的獲取流程是什么,所以本文就給大家詳細(xì)講解一下MyBatis的SqlSession獲取流程,需要的朋友可以參考下
    2023-07-07
  • Java?Web中Ajax技術(shù)使用方法介紹

    Java?Web中Ajax技術(shù)使用方法介紹

    ajax技術(shù)是使頁(yè)面能局部刷新的一種技術(shù),下面這篇文章主要給大家介紹了關(guān)于JavaWeb之Ajax的基本使用與實(shí)戰(zhàn)案例的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-10-10
  • Log4j日志記錄框架配置及用法解析

    Log4j日志記錄框架配置及用法解析

    這篇文章主要介紹了Log4j日志記錄框架配置及用法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Java基礎(chǔ)學(xué)習(xí)之ArrayList類(lèi)概述與常用方法

    Java基礎(chǔ)學(xué)習(xí)之ArrayList類(lèi)概述與常用方法

    這篇文章主要為大家簡(jiǎn)單的介紹Java中ArrayList類(lèi)的概述、常用方法及存儲(chǔ)字符串并遍歷,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2022-08-08
  • Java多線程定時(shí)器Timer原理及實(shí)現(xiàn)

    Java多線程定時(shí)器Timer原理及實(shí)現(xiàn)

    這篇文章主要介紹了Java多線程定時(shí)器Timer原理及實(shí)現(xiàn),涉及Timer的schedule的使用,定時(shí)器Timer的schedule等相關(guān)內(nèi)容以及代碼示例,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • JavaFX實(shí)現(xiàn)簡(jiǎn)易時(shí)鐘效果(二)

    JavaFX實(shí)現(xiàn)簡(jiǎn)易時(shí)鐘效果(二)

    這篇文章主要為大家詳細(xì)介紹了JavaFX實(shí)現(xiàn)簡(jiǎn)易時(shí)鐘效果的第二篇,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-11-11

最新評(píng)論