中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Spring靜態代理和動態代理概念及使用方法是什么

發布時間:2023-02-27 10:37:34 來源:億速云 閱讀:112 作者:iii 欄目:開發技術

這篇文章主要講解了“Spring靜態代理和動態代理概念及使用方法是什么”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Spring靜態代理和動態代理概念及使用方法是什么”吧!

代理模式

在學習 AOP 之前,我們先來了解下代理模式, 代理模式分為靜態代理以及動態代理,屬于23中設計模式之一。 AOP 的底層機制就是動態代理。

Spring靜態代理和動態代理概念及使用方法是什么

作用:

通過代理類為原始類增加額外的功能

1、靜態代理

1)案例展示

【1】定義一個 Teacher 接口,接口中定義兩個方法:teachOnLine 和 teachOffLine。

package cn.gc.spring03.interfce;
public interface Teacher {
    String teachOnLine(String course);
    String teachOffLine(String course);
}

【2】定義一個實現 Teacher 接口的 TeacherA 實現類,代碼如下:

package cn.gc.spring03.interfce.impl;
import cn.gc.spring03.interfce.Teacher;
public class TeacherA implements Teacher {
    @Override
    public String teachOnLine(String course) {
        System.out.println("開始"+course+"課程線上教學");
        return course+"課程線上教學";
    }
    @Override
    public String teachOffLine(String course) {
        System.out.println("開始"+course+"課程線下教學");
        return course+"課程線下教學";
    }
}

【3】現在我們要在兩個方法中的 開始課程教學 的前后添加上下課鈴聲的功能,此時我們再定義一個實現 Teacher 接口的靜態代理類 TeacherAStaticProxy,代碼如下:

package cn.gc.spring03.proxy;
import cn.gc.spring03.interfce.Teacher;
import cn.gc.spring03.interfce.impl.TeacherA;
public class TeacherAStaticProxy implements Teacher {
    TeacherA teacherA=new TeacherA();
    @Override
    public String teachOnLine(String course) {
        System.out.println(course+"課程上課時間到了");
        String s = teacherA.teachOnLine(course);
        System.out.println(course+"課程下課時間到了");
        return s;
    }
    @Override
    public String teachOffLine(String course) {
        System.out.println(course+"課程上課時間到了");
        String s = teacherA.teachOffLine(course);
        System.out.println(course+"課程下課時間到了");
        return s;
    }
}

【4】運行效果如下

Spring靜態代理和動態代理概念及使用方法是什么

2)靜態代理優缺點

(1)優點 :在不修改目標對象的功能前提下,能通過代理對象對目標功能擴展;可以使得真實角色更加純粹,不再去關注一些公共的事情;公共的業務由代理來完成,實現了業務的分工。

(2)缺點 :因為代理對象需要與目標對象實現一樣的接口,所以會很多代理類 ,一旦接口增加方法,目標對象與代理對象都要維護,工作量變大,開發效率降低。

3)開發代理對象的原則

  • 代理對象和目標對象實現相同的接口

  • 代理對象依賴于目標對象

2、動態代理

在不改變原來的代碼的情況下,實現了對原有功能的增強,這是 AOP 中最核心的思想。

AOP:縱向開發,橫向開發

Spring靜態代理和動態代理概念及使用方法是什么

1)簡介

動態代理的角色和靜態代理的一樣。但是動態代理的代理類是動態生成的,而靜態代理的代理類是提前寫好的。

動態代理分為兩類,一類是基于接口動態代理(JDK),一類是基于類的動態代理(CGLib)。

2)基于接口動態代理(JDK)

程序運行的過程中,通過 JDK 提供代理技術動態的為某個類產生動態代理對象的過程。

開發代理對象的原則:

  • 代理對象,不需要實現接口,但是目標對象要實現接口,否則不能用JDK動態代理。

  • 代理對象的生成,是利用JDK的API,動態的在內存中構建代理對象。

  • 動態代理也叫做 :JDK代理、接口代理。

JDK 的動態代理需要了解兩個類:

核心 : InvocationHandler (調用處理程序) 和 Proxy (代理)

Spring靜態代理和動態代理概念及使用方法是什么

實現步驟:在上面案例的基礎上實現。

創建一個基于 JDK 的代理工具類 DynamicProxy 類:

package cn.gc.spring03.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*
 * 基于JDK的代理工具類
 */
public class DynamicProxy {
    //被代理對象
    private Object target;
    public DynamicProxy(Object obj) {
        this.target = obj;
    }
    //生成代理對象
    public Object getProxy() {
        //獲取類加載器
        ClassLoader classLoader = target.getClass().getClassLoader();
        //獲取被代理對象實現的所有接口
        Class<?>[] interfaces = target.getClass().getInterfaces();
        //增強功能代碼編寫的位置
        InvocationHandler invocationHandler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                // 增強的功能
                System.out.println(args[0] + "課程上課時間到了");
                // 通過反射執行目標方法
                Object invoke = method.invoke(target, args);
                // 增強的功能
                System.out.println(args[0] + "課程下課時間到了");
                return invoke;
            }
        };
        Object o = Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
        return o;
    }
}

測試:

    @Test
    public void test02() {
        Teacher teacher  = new TeacherA();
        DynamicProxy dynamicProxy = new DynamicProxy(teacher);
        Teacher teacherProxy = (Teacher) dynamicProxy.getProxy();
        teacherProxy.teachOnLine("Java");
        System.out.println("______________________");
        teacherProxy.teachOnLine("C++");
    }

運行效果:

Spring靜態代理和動態代理概念及使用方法是什么

3)基于類的動態代理(CGLib)

開發代理對象的原則:

  • 代理對象無需和原始類對象實現相同的接口

  • 代理對象和原始類對象要存在父子類關系

CGLib 的動態代理需要了解兩個類:

  • 核心 : Enhancer 和 MethodInterceptor

實現步驟

創建一個 Aoo 類:

package cn.gc.spring03.interfce.impl;
public class Aoo {
    public String test01(String info){
        System.out.println("Aoo中的test01方法被調用。");
        return info;
    }
}

創建一個基于 CGLib 的代理工具類 CglibProxy 類:

package cn.gc.spring03.proxy;
import org.springframework.cglib.proxy.Callback;
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 {
    private Object target;
    public CglibProxy(Object obj){
        this.target=obj;
    }
    public Object getProxy(){
        Enhancer enhancer=new Enhancer();
        //設置類加載器
        enhancer.setClassLoader(CglibProxy.class.getClassLoader());
        //設置被代理對象
        enhancer.setSuperclass(target.getClass());
        //增強功能代碼編寫的位置
        MethodInterceptor methodInterceptor=new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println("-------------cglib log--------------");
                Object invoke = method.invoke(target, objects);
                System.out.println("-------------cglib log--------------");
                return invoke;
            }
        };
        enhancer.setCallback(methodInterceptor);
        //代理對象
        Object o = enhancer.create();
        return o;
    }
}

測試:

    @Test
    public void test03() {
        Aoo aoo=new Aoo();
        CglibProxy cglibProxy = new CglibProxy(aoo);
        Aoo proxy = (Aoo) cglibProxy.getProxy();
        String info = proxy.test01("java");
        System.out.println("info = " + info);
    }

運行效果:

Spring靜態代理和動態代理概念及使用方法是什么

4)動態代理的優勢

  • 可以使得真實角色更加純粹,不再去關注一些公共的事情。

  • 公共的業務由代理來完成,實現了業務的分工。

  • 公共業務發生擴展時變得更加集中和方便。

  • 一個動態代理,一般代理某一類業務。

  • 一個動態代理可以代理多個類,代理的是接口。

Spring靜態代理和動態代理概念及使用方法是什么

感謝各位的閱讀,以上就是“Spring靜態代理和動態代理概念及使用方法是什么”的內容了,經過本文的學習后,相信大家對Spring靜態代理和動態代理概念及使用方法是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

普格县| 芦山县| 紫云| 苏州市| 海阳市| 南宁市| 新密市| 惠来县| 衡阳县| 通河县| 抚远县| 崇州市| 龙游县| 山阳县| 焦作市| 囊谦县| 阳新县| 库尔勒市| 屯留县| 丹凤县| 天气| 桓台县| 新化县| 隆子县| 土默特左旗| 平和县| 独山县| 喀什市| 芮城县| 勃利县| 临城县| 乌拉特前旗| 镇江市| 修武县| 滨海县| 隆林| 墨脱县| 自治县| 玛沁县| 合山市| 铜陵市|