成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

深入探究動(dòng)態(tài)代理:JDK 與 CGLIB 的實(shí)現(xiàn)奧秘與差異剖析

開(kāi)發(fā) 前端
當(dāng)目標(biāo)對(duì)象有接口且注重開(kāi)發(fā)便捷性、遵循接口編程規(guī)范時(shí),JDK 動(dòng)態(tài)代理是首選。例如在標(biāo)準(zhǔn)的企業(yè)級(jí) Java 應(yīng)用開(kāi)發(fā)中,服務(wù)層接口常使用 JDK 代理實(shí)現(xiàn)日志記錄、權(quán)限驗(yàn)證等 AOP 功能,與 Spring 等框架無(wú)縫集成。

在 Java 編程領(lǐng)域,動(dòng)態(tài)代理是一種強(qiáng)大的設(shè)計(jì)模式,它允許開(kāi)發(fā)者在運(yùn)行時(shí)創(chuàng)建代理對(duì)象,對(duì)目標(biāo)對(duì)象的行為進(jìn)行增強(qiáng)、監(jiān)控或修改,而無(wú)需在編譯期就確定代理的具體邏輯。這一特性在諸多框架中廣泛應(yīng)用,如 Spring AOP(面向切面編程),為實(shí)現(xiàn)橫切面關(guān)注點(diǎn)的模塊化提供了關(guān)鍵支撐。

一、JDK 動(dòng)態(tài)代理實(shí)現(xiàn)原理

JDK 動(dòng)態(tài)代理依托于 Java 反射機(jī)制構(gòu)建,核心涉及  java.lang.reflect  包下的幾個(gè)重要類。

首先,需要定義一個(gè)接口,該接口代表目標(biāo)對(duì)象與代理對(duì)象共同遵循的行為規(guī)范。假設(shè)我們有一個(gè)簡(jiǎn)單的圖形繪制接口  Shape :

public interface Shape {
    void draw();
}
接著是目標(biāo)類實(shí)現(xiàn)此接口,例如  Circle  類:
public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a circle");
    }
}

創(chuàng)建代理對(duì)象的關(guān)鍵在于實(shí)現(xiàn)  java.lang.reflect.InvocationHandler  接口,它定義了一個(gè)  invoke  方法,用于處理代理對(duì)象上所有方法的調(diào)用邏輯:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class ShapeInvocationHandler implements InvocationHandler {
    private final Object target;
    public ShapeInvocationHandler(Object target) {
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 在目標(biāo)方法調(diào)用前添加額外邏輯,如日志記錄
        System.out.println("Before method invocation");
        Object result = method.invoke(target, args);
        // 在目標(biāo)方法調(diào)用后添加額外邏輯,如性能統(tǒng)計(jì)
        System.out.println("After method invocation");
        return result;
    }
}

最后,通過(guò)  java.lang.reflect.Proxy  類生成代理對(duì)象:

import java.lang.reflect.Proxy;
public class Main {
    public static void main(String[] args) {
        Shape circle = new Circle();
        ShapeInvocationHandler handler = new ShapeInvocationHandler(circle);
        Shape proxyShape = (Shape) Proxy.newProxyInstance(
                Shape.class.getClassLoader(),
                new Class[]{Shape.class},
                handler);
        proxyShape.draw();
    }
}

在上述代碼中,當(dāng)調(diào)用代理對(duì)象  proxyShape  的  draw  方法時(shí),實(shí)際上控制權(quán)轉(zhuǎn)移到  ShapeInvocationHandler  的  invoke  方法,在此可以靈活插入前置、后置邏輯,實(shí)現(xiàn)對(duì)目標(biāo)對(duì)象方法的動(dòng)態(tài)增強(qiáng)。

二、CGLIB 動(dòng)態(tài)代理實(shí)現(xiàn)原理

CGLIB(Code Generation Library)動(dòng)態(tài)代理采取了截然不同的字節(jié)碼生成策略。它不依賴接口,而是直接對(duì)目標(biāo)類進(jìn)行字節(jié)碼擴(kuò)展。

引入 CGLIB 相關(guān)依賴后,以同樣的  Circle  類為例(此時(shí)無(wú)需實(shí)現(xiàn)接口):

public class Circle {
    public void draw() {
        System.out.println("Drawing a circle");
    }
}

創(chuàng)建一個(gè)實(shí)現(xiàn)  net.sf.cglib.proxy.MethodInterceptor  接口的攔截器類,它類似于 JDK 代理中的  InvocationHandler :

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibShapeInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("CGLIB: Before method call");
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("CGLIB: After method call");
        return result;
    }
}

利用  net.sf.cglib.proxy.Enhancer  類生成代理對(duì)象:

import net.sf.cglib.proxy.Enhancer;
public class Main {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Circle.class);
        enhancer.setCallback(new CglibShapeInterceptor());
        Circle proxyCircle = (Circle) enhancer.create();
        proxyCircle.draw();
    }
}

這里, Enhancer  通過(guò)修改目標(biāo)類的字節(jié)碼,在原始方法執(zhí)行前后織入自定義邏輯,生成的代理對(duì)象繼承自目標(biāo)類,能直接調(diào)用目標(biāo)類非  private  的方法,無(wú)需像 JDK 代理那樣依賴接口。

三、JDK 動(dòng)態(tài)代理與 CGLIB 動(dòng)態(tài)代理的區(qū)別

(一)實(shí)現(xiàn)基礎(chǔ)

- JDK 動(dòng)態(tài)代理:基于接口實(shí)現(xiàn),要求目標(biāo)對(duì)象必須實(shí)現(xiàn)至少一個(gè)接口。它利用 Java 反射在運(yùn)行時(shí)動(dòng)態(tài)生成代理類,該代理類同樣實(shí)現(xiàn)目標(biāo)對(duì)象的接口,通過(guò)接口回調(diào)機(jī)制將方法調(diào)用轉(zhuǎn)發(fā)至  InvocationHandler  處理。

- CGLIB 動(dòng)態(tài)代理:基于繼承機(jī)制,直接操作目標(biāo)類的字節(jié)碼,生成目標(biāo)類的子類作為代理對(duì)象。它通過(guò)重寫子類方法,在其中插入攔截邏輯,調(diào)用父類(即目標(biāo)類)原始方法實(shí)現(xiàn)功能,無(wú)需目標(biāo)對(duì)象有接口實(shí)現(xiàn)。

(二)性能表現(xiàn)

- 在創(chuàng)建代理對(duì)象階段,JDK 動(dòng)態(tài)代理相對(duì)較快,因?yàn)樗恍杌诮涌谛畔⒗梅瓷渖珊?jiǎn)單代理類結(jié)構(gòu);而 CGLIB 需要通過(guò)復(fù)雜的字節(jié)碼生成技術(shù)創(chuàng)建子類,耗時(shí)較長(zhǎng)。

- 但在方法調(diào)用時(shí),JDK 動(dòng)態(tài)代理由于每次都要經(jīng)過(guò)反射查找方法等操作,性能開(kāi)銷較大;CGLIB 代理對(duì)象調(diào)用方法類似普通對(duì)象調(diào)用,因?yàn)榉椒ㄒ言谧止?jié)碼層面重寫優(yōu)化,若頻繁調(diào)用代理方法,CGLIB 在性能上更具優(yōu)勢(shì)。

(三)適用場(chǎng)景

- 當(dāng)目標(biāo)對(duì)象有接口且注重開(kāi)發(fā)便捷性、遵循接口編程規(guī)范時(shí),JDK 動(dòng)態(tài)代理是首選。例如在標(biāo)準(zhǔn)的企業(yè)級(jí) Java 應(yīng)用開(kāi)發(fā)中,服務(wù)層接口常使用 JDK 代理實(shí)現(xiàn)日志記錄、權(quán)限驗(yàn)證等 AOP 功能,與 Spring 等框架無(wú)縫集成。

- 若目標(biāo)對(duì)象沒(méi)有接口,或者需要對(duì) final 修飾的類進(jìn)行代理(JDK 代理無(wú)法做到,因 final 類不可繼承),CGLIB 動(dòng)態(tài)代理便能大顯身手。像一些遺留代碼改造、底層工具類增強(qiáng)場(chǎng)景,CGLIB 可突破接口限制,靈活實(shí)現(xiàn)代理需求。

JDK 動(dòng)態(tài)代理與 CGLIB 動(dòng)態(tài)代理各具特色,它們從不同角度為 Java 開(kāi)發(fā)者提供了動(dòng)態(tài)代理的實(shí)現(xiàn)路徑,深入理解二者原理與區(qū)別,有助于在面對(duì)復(fù)雜多變的編程需求時(shí),精準(zhǔn)選擇合適的代理方式,打造高效、健壯的 Java 應(yīng)用。

責(zé)任編輯:武曉燕 來(lái)源: 程序員conan
相關(guān)推薦

2024-01-04 07:42:44

JavaCGLIBJDK

2023-12-06 08:23:44

代理模式設(shè)計(jì)模式

2021-04-22 09:58:15

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

2022-09-01 10:40:29

SpringAOPJDK

2024-03-07 08:22:51

Java機(jī)制元數(shù)據(jù)

2021-07-14 11:07:56

AOPJDKCglib

2023-09-28 09:03:56

開(kāi)源搜索分析引擎

2024-09-05 09:35:58

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

2024-01-26 08:33:14

JDK17JDK11版本

2010-09-01 09:29:51

CSS層疊CSS繼承

2010-08-16 10:25:23

DIVSPAN

2012-09-28 10:20:14

IBMdw

2012-09-27 09:47:43

SpringJava面向?qū)ο?/a>

2013-05-07 11:43:47

2023-06-07 07:43:57

數(shù)據(jù)庫(kù)JOIN類型

2024-01-31 23:47:17

i++++i編碼

2020-10-25 17:11:29

JDK代理監(jiān)控

2022-11-15 09:57:51

Java接口

2010-09-30 09:16:04

cookieJ2ME

2011-11-24 21:03:10

ibmdw
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 一级网站 | 午夜精品一区二区三区在线视频 | 日韩精品一区二区三区视频播放 | 在线观看中文字幕 | 欧美三级久久久 | 在线成人 | 日韩在线一区二区三区 | 99久久精品国产毛片 | 一区二区在线观看av | 日韩精品极品视频在线观看免费 | hitomi一区二区三区精品 | 欧美久久一级 | 天天爽夜夜操 | 精品影院 | 国产精品国产三级国产aⅴ原创 | 中文字幕第九页 | 在线观看日韩精品视频 | 亚洲精品99 | 一级全黄少妇性色生活免费看 | 国产高清区 | 久久中文字幕一区 | 中文字幕一区二区三区四区五区 | 亚洲一区电影 | 国产欧美精品一区 | 网站国产 | 日韩高清在线观看 | 日韩精品在线看 | 久久精品中文字幕 | 免费视频一区二区三区在线观看 | 日韩中文字幕一区二区 | 亚洲精品成人网 | 男人阁久久 | 99精品一区二区三区 | 久久精品毛片 | 国产黄视频在线播放 | 国产观看| 国产精品视频在线观看 | 久久久久亚洲精品 | 欧美午夜精品 | 国产一区二区三区视频 | 亚洲精品国产一区 |