自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

拼多多二面:Spring AOP 和 AspectJ 的區(qū)別是什么?

開發(fā)
本文我們分析了 Spring AOP 和 AspectJ 的實(shí)現(xiàn)原理,并且通過(guò)示例展示了兩者如如何使用它們。

Spring AOP和 AspectJ 是工作中經(jīng)常使用的兩個(gè)的 AOP框架,那么,它們是如何工作的??jī)烧咧g有什么區(qū)別?我們?cè)撊绾芜x擇?這篇文章來(lái)聊一聊。

一、實(shí)現(xiàn)原理

1. Spring AOP 的實(shí)現(xiàn)原理

Spring AOP,全稱 Aspect-Oriented Programming,中文翻譯為面向切面編程,主要是基于代理模式來(lái)實(shí)現(xiàn)面向切面編程。其核心原理包括 3個(gè)步驟:

  • 動(dòng)態(tài)代理:Spring AOP 使用 JDK 動(dòng)態(tài)代理或 CGLIB(Code Generation Library)生成代理對(duì)象。當(dāng)被代理的目標(biāo)對(duì)象實(shí)現(xiàn)了接口時(shí),Spring 默認(rèn)使用 JDK 動(dòng)態(tài)代理;否則,使用 CGLIB 生成子類代理。
  • 織入機(jī)制:在運(yùn)行時(shí),通過(guò)代理對(duì)象攔截方法調(diào)用,根據(jù)配置的切面(Aspect)和通知(Advice)執(zhí)行相應(yīng)的增強(qiáng)邏輯(如前置、后置、環(huán)繞等)。
  • 代理鏈:如果有多個(gè)切面,需要按照一定的順序?qū)δ繕?biāo)對(duì)象進(jìn)行多層代理。

2. AspectJ 的實(shí)現(xiàn)原理

AspectJ 是一個(gè)功能更強(qiáng)大的 AOP 框架,提供了更豐富的切面功能和更靈活的織入機(jī)制。其實(shí)現(xiàn)原理也包括 3個(gè)步驟:

織入時(shí)機(jī):

  • 編譯時(shí)織入(Compile-time Weaving):在源代碼編譯成字節(jié)碼時(shí),將切面邏輯織入目標(biāo)類。
  • 類加載時(shí)織入(Load-time Weaving):在類被加載到 JVM 時(shí),通過(guò)特定的類加載器將切面邏輯織入目標(biāo)類。
  • 二進(jìn)制織入(Binary Weaving):對(duì)已經(jīng)編譯好的字節(jié)碼進(jìn)行后期修改,加入切面邏輯。
  • 字節(jié)碼操作:AspectJ 直接操作字節(jié)碼,允許對(duì)更細(xì)粒度的連接點(diǎn)(如字段賦值、構(gòu)造方法調(diào)用等)進(jìn)行攔截和增強(qiáng)。
  • 豐富的切點(diǎn)表達(dá)式:支持更復(fù)雜和精確的切點(diǎn)定義,涵蓋更多的連接點(diǎn)類型。

二、兩者區(qū)別

在分析完 Spring AOP和 AspectJ 的工作原理之后,我們來(lái)看看兩者的區(qū)別。關(guān)于 Spring AOP和 AspectJ的區(qū)別,可以總結(jié)成下表:

特性

Spring AOP

AspectJ

實(shí)現(xiàn)方式

基于動(dòng)態(tài)代理(JDK代理或CGLIB)

基于字節(jié)碼織入(編譯時(shí)、類加載時(shí)、二進(jìn)制)

切點(diǎn)范圍

主要面向方法級(jí)別的連接點(diǎn)

支持方法、構(gòu)造方法、字段、異常等多種連接點(diǎn)

織入時(shí)機(jī)

運(yùn)行時(shí)通過(guò)代理實(shí)現(xiàn)

編譯時(shí)、類加載時(shí)或二進(jìn)制后期織入

性能

由于使用代理,性能開銷相對(duì)較小,但功能有限

由于織入在編譯或類加載時(shí)完成,運(yùn)行時(shí)性能更優(yōu),功能更強(qiáng)大

功能豐富度

提供基本的AOP功能,如前置、后置、環(huán)繞通知

提供更豐富的AOP功能,包括更復(fù)雜的切點(diǎn)表達(dá)式和連接點(diǎn)類型

使用復(fù)雜度

易于集成和使用,特別是在Spring應(yīng)用中

相對(duì)復(fù)雜,需要了解更多的織入機(jī)制和配置

適用場(chǎng)景

適合大多數(shù)常見的AOP需求,如事務(wù)管理、日志記錄等

適合需要更深入和復(fù)雜AOP功能的場(chǎng)景,如底層框架開發(fā)、對(duì)非Spring管理對(duì)象進(jìn)行增強(qiáng)等

三、代碼示例

為了更好地理解 Spring AOP 和 AspectJ,下面我們以如何進(jìn)行日志記錄為例,展示兩者的實(shí)現(xiàn)。

1. 使用 Spring AOP

步驟:

(1) 添加依賴(以 Maven 為例):

<dependencies>
    <!-- Spring AOP -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>5.3.23</version>
    </dependency>
    <!-- AspectJ Weaver -->
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.19</version>
    </dependency>
</dependencies>

(2) 定義業(yè)務(wù)類:

package com.yuanjava.service;

public class UserService {
    public void addUser(String name) {
        System.out.println("Add user: " + name);
    }
}

(3) 定義切面類:

package com.yuanjava.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class LoggingAspect {

    @Before("execution(* com.yuanjava.service.UserService.addUser(..))")
    public void logBefore() {
        System.out.println("Add log before method");
    }
}

(4) 配置 Spring 容器(使用 Java 配置):

package com.yuanjava.config;

import com.example.aspect.LoggingAspect;
import com.example.service.UserService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@EnableAspectJAutoProxy// 啟用AOP自動(dòng)代理
publicclass AppConfig {

    @Bean
    public UserService userService() {
        returnnew UserService();
    }

    @Bean
    public LoggingAspect loggingAspect() {
        returnnew LoggingAspect();
    }
}

(5) 運(yùn)行測(cè)試:

package com.yuanjava;

import com.yuanjava.config.AppConfig;
import com.yuanjava.service.UserService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class AOPSpringDemo {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        UserService userService = context.getBean(UserService.class);
        userService.addUser("猿java");
        context.close();
    }
}

輸出:

Add log before method
Add user: 猿java

2. 使用 AspectJ

步驟:

(1) 添加依賴(以 Maven 為例):

<dependencies>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.9.19</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjtools</artifactId>
        <version>1.9.19</version>
    </dependency>
</dependencies>

(2) 定義業(yè)務(wù)類:

package com.yuanjava.service;

public class UserService {
    public void addUser(String name) {
        System.out.println("Add user: " + name);
    }
}

(3) 定義切面類:

package com.yuanjava.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class LoggingAspect {

    @Before("execution(* com.yuanjava.service.UserService.addUser(..))")
    public void logBefore() {
        System.out.println("Add log before method");
    }
}

(4) 編譯時(shí)織入(使用 AspectJ 編譯器 ajc):

  • 假設(shè)項(xiàng)目結(jié)構(gòu)如下:
src/
├── com/yuanjava/service/UserService.java
├── com/yuanjava/aspect/LoggingAspect.java
  • 運(yùn)行以下命令進(jìn)行編譯和織入:
ajc -1.8 -d bin -sourcepath src src/com/yuanjava/service/UserService.java src/com/yuanjava/aspect/LoggingAspect.java

(5) 運(yùn)行測(cè)試:

package com.yuanjava;

import com.yuanjava.service.UserService;

public class AspectJDemos {
    public static void main(String[] args) {
        UserService userService = new UserService();
        userService.addUser("猿java");
    }
}

輸出:

Add log before method
Add user: 猿java

四、使用場(chǎng)景

1. Spring AOP

從整體來(lái)看,Spring AOP的使用場(chǎng)景可以包含以下幾個(gè)方面:

  • 事務(wù)管理:在業(yè)務(wù)方法執(zhí)行前后開啟和提交事務(wù)。
  • 日志記錄:記錄方法執(zhí)行的日志,如進(jìn)入、退出、異常等。
  • 權(quán)限檢查:在方法調(diào)用前進(jìn)行權(quán)限驗(yàn)證。
  • 緩存管理:在方法執(zhí)行前后進(jìn)行緩存的查詢與更新。
  • 性能監(jiān)控:監(jiān)控方法的執(zhí)行時(shí)間,進(jìn)行性能分析。

2. AspectJ

從整體來(lái)看,AspectJ的使用場(chǎng)景可以包含以下幾個(gè)方面:

  • 底層框架開發(fā):對(duì)第三方庫(kù)或應(yīng)用程序進(jìn)行更深入的字節(jié)碼增強(qiáng)。
  • 跨庫(kù)的數(shù)據(jù)訪問(wèn):在數(shù)據(jù)訪問(wèn)層進(jìn)行統(tǒng)一的攔截和處理。
  • 復(fù)雜的業(yè)務(wù)邏輯攔截:需要對(duì)構(gòu)造方法、字段賦值等進(jìn)行攔截的場(chǎng)景。
  • 無(wú)Spring環(huán)境的項(xiàng)目:在不使用 Spring 框架的項(xiàng)目中實(shí)現(xiàn) AOP 功能。
  • 性能優(yōu)化:需要高性能的字節(jié)碼級(jí)別的增強(qiáng),減少運(yùn)行時(shí)開銷。
  • 適用理由:AspectJ 提供更強(qiáng)大的 AOP 功能和更靈活的織入機(jī)制,適用于需要精細(xì)控制切面織入時(shí)機(jī)和范圍的復(fù)雜應(yīng)用。

五、總結(jié)

本文,我們分析了 Spring AOP 和 AspectJ 的實(shí)現(xiàn)原理,并且通過(guò)示例展示了兩者如如何使用它們。

  • Spring AOP:Spring AOP 集成簡(jiǎn)單,適用于大多數(shù)基于 Spring 的應(yīng)用,易于集成和配置,適合實(shí)現(xiàn)常見的橫切關(guān)注點(diǎn),如事務(wù)管理和日志記錄。
  • AspectJ:AspectJ 提供更強(qiáng)大的 AOP 功能和更靈活的織入機(jī)制,適用于需要深入字節(jié)碼級(jí)別操作或在非 Spring 環(huán)境中實(shí)現(xiàn) AOP 的場(chǎng)景。

在實(shí)際業(yè)務(wù)中,選擇哪種 AOP框架取決于項(xiàng)目的具體需求和團(tuán)隊(duì)的技術(shù)棧選擇,作為 Java程序員,強(qiáng)烈建議掌握兩者的工作原理。

責(zé)任編輯:趙寧寧 來(lái)源: 猿java
相關(guān)推薦

2024-10-15 10:59:18

Spring MVCJava開發(fā)

2023-10-23 11:07:37

HTTPRPC

2022-11-15 10:03:34

2024-10-30 16:12:14

2016-03-21 10:40:53

RDDSpark SQL數(shù)據(jù)集

2024-12-30 07:20:00

Redis數(shù)據(jù)庫(kù)MySQL

2025-02-06 08:44:11

MySQLEXISTSIN

2018-05-21 21:26:59

Apache HiveHbaseSQL

2021-10-27 08:54:11

Pythonencodeencoding

2015-02-26 10:29:41

Google百度

2025-03-20 08:00:00

@LazySpring開發(fā)

2017-11-21 22:49:10

2022-09-03 08:03:14

UbuntuDebian

2021-02-17 00:30:41

機(jī)器學(xué)習(xí)深度學(xué)習(xí)人工智能

2012-12-10 09:44:04

路由器本地回路

2022-11-18 16:10:03

云計(jì)算虛擬機(jī)

2023-10-24 09:07:14

CookieSessionHTTP

2020-09-18 15:10:51

Web前端技術(shù)

2023-08-29 09:50:42

Unix shellLinux

2024-10-22 16:26:11

點(diǎn)贊
收藏

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