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

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

開發
本文我們分析了 Spring AOP 和 AspectJ 的實現原理,并且通過示例展示了兩者如如何使用它們。

Spring AOP和 AspectJ 是工作中經常使用的兩個的 AOP框架,那么,它們是如何工作的?兩者之間有什么區別?我們該如何選擇?這篇文章來聊一聊。

一、實現原理

1. Spring AOP 的實現原理

Spring AOP,全稱 Aspect-Oriented Programming,中文翻譯為面向切面編程,主要是基于代理模式來實現面向切面編程。其核心原理包括 3個步驟:

  • 動態代理:Spring AOP 使用 JDK 動態代理或 CGLIB(Code Generation Library)生成代理對象。當被代理的目標對象實現了接口時,Spring 默認使用 JDK 動態代理;否則,使用 CGLIB 生成子類代理。
  • 織入機制:在運行時,通過代理對象攔截方法調用,根據配置的切面(Aspect)和通知(Advice)執行相應的增強邏輯(如前置、后置、環繞等)。
  • 代理鏈:如果有多個切面,需要按照一定的順序對目標對象進行多層代理。

2. AspectJ 的實現原理

AspectJ 是一個功能更強大的 AOP 框架,提供了更豐富的切面功能和更靈活的織入機制。其實現原理也包括 3個步驟:

織入時機:

  • 編譯時織入(Compile-time Weaving):在源代碼編譯成字節碼時,將切面邏輯織入目標類。
  • 類加載時織入(Load-time Weaving):在類被加載到 JVM 時,通過特定的類加載器將切面邏輯織入目標類。
  • 二進制織入(Binary Weaving):對已經編譯好的字節碼進行后期修改,加入切面邏輯。
  • 字節碼操作:AspectJ 直接操作字節碼,允許對更細粒度的連接點(如字段賦值、構造方法調用等)進行攔截和增強。
  • 豐富的切點表達式:支持更復雜和精確的切點定義,涵蓋更多的連接點類型。

二、兩者區別

在分析完 Spring AOP和 AspectJ 的工作原理之后,我們來看看兩者的區別。關于 Spring AOP和 AspectJ的區別,可以總結成下表:

特性

Spring AOP

AspectJ

實現方式

基于動態代理(JDK代理或CGLIB)

基于字節碼織入(編譯時、類加載時、二進制)

切點范圍

主要面向方法級別的連接點

支持方法、構造方法、字段、異常等多種連接點

織入時機

運行時通過代理實現

編譯時、類加載時或二進制后期織入

性能

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

由于織入在編譯或類加載時完成,運行時性能更優,功能更強大

功能豐富度

提供基本的AOP功能,如前置、后置、環繞通知

提供更豐富的AOP功能,包括更復雜的切點表達式和連接點類型

使用復雜度

易于集成和使用,特別是在Spring應用中

相對復雜,需要了解更多的織入機制和配置

適用場景

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

適合需要更深入和復雜AOP功能的場景,如底層框架開發、對非Spring管理對象進行增強等

三、代碼示例

為了更好地理解 Spring AOP 和 AspectJ,下面我們以如何進行日志記錄為例,展示兩者的實現。

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) 定義業務類:

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自動代理
publicclass AppConfig {

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

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

(5) 運行測試:

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) 定義業務類:

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) 編譯時織入(使用 AspectJ 編譯器 ajc):

  • 假設項目結構如下:
src/
├── com/yuanjava/service/UserService.java
├── com/yuanjava/aspect/LoggingAspect.java
  • 運行以下命令進行編譯和織入:
ajc -1.8 -d bin -sourcepath src src/com/yuanjava/service/UserService.java src/com/yuanjava/aspect/LoggingAspect.java

(5) 運行測試:

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

四、使用場景

1. Spring AOP

從整體來看,Spring AOP的使用場景可以包含以下幾個方面:

  • 事務管理:在業務方法執行前后開啟和提交事務。
  • 日志記錄:記錄方法執行的日志,如進入、退出、異常等。
  • 權限檢查:在方法調用前進行權限驗證。
  • 緩存管理:在方法執行前后進行緩存的查詢與更新。
  • 性能監控:監控方法的執行時間,進行性能分析。

2. AspectJ

從整體來看,AspectJ的使用場景可以包含以下幾個方面:

  • 底層框架開發:對第三方庫或應用程序進行更深入的字節碼增強。
  • 跨庫的數據訪問:在數據訪問層進行統一的攔截和處理。
  • 復雜的業務邏輯攔截:需要對構造方法、字段賦值等進行攔截的場景。
  • 無Spring環境的項目:在不使用 Spring 框架的項目中實現 AOP 功能。
  • 性能優化:需要高性能的字節碼級別的增強,減少運行時開銷。
  • 適用理由:AspectJ 提供更強大的 AOP 功能和更靈活的織入機制,適用于需要精細控制切面織入時機和范圍的復雜應用。

五、總結

本文,我們分析了 Spring AOP 和 AspectJ 的實現原理,并且通過示例展示了兩者如如何使用它們。

  • Spring AOP:Spring AOP 集成簡單,適用于大多數基于 Spring 的應用,易于集成和配置,適合實現常見的橫切關注點,如事務管理和日志記錄。
  • AspectJ:AspectJ 提供更強大的 AOP 功能和更靈活的織入機制,適用于需要深入字節碼級別操作或在非 Spring 環境中實現 AOP 的場景。

在實際業務中,選擇哪種 AOP框架取決于項目的具體需求和團隊的技術棧選擇,作為 Java程序員,強烈建議掌握兩者的工作原理。

責任編輯:趙寧寧 來源: 猿java
相關推薦

2024-10-15 10:59:18

Spring MVCJava開發

2023-10-23 11:07:37

HTTPRPC

2022-11-15 10:03:34

2024-10-30 16:12:14

2024-12-30 07:20:00

Redis數據庫MySQL

2016-03-21 10:40:53

RDDSpark SQL數據集

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開發

2017-11-21 22:49:10

2022-09-03 08:03:14

UbuntuDebian

2012-12-10 09:44:04

路由器本地回路

2021-02-17 00:30:41

機器學習深度學習人工智能

2022-11-18 16:10:03

云計算虛擬機

2020-09-18 15:10:51

Web前端技術

2023-10-24 09:07:14

CookieSessionHTTP

2023-08-29 09:50:42

Unix shellLinux

2024-10-22 16:26:11

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美日韩国产高清 | 欧美久久国产精品 | 激情欧美一区二区三区 | 99热这里 | 黄色欧美视频 | 午夜免费福利影院 | 中文字幕一区二区三区四区五区 | 欧美日韩国产一区二区三区 | 亚洲欧美中文日韩在线v日本 | 91看片| 在线观看亚洲精品视频 | 日韩精品一区二 | 成人美女免费网站视频 | 亚洲国产精品一区二区www | 九色porny自拍视频 | 成人福利片 | 国产精品久久久久久久久久久久 | 日韩av在线不卡 | 亚洲人人 | 成人国产免费视频 | 超碰成人在线观看 | 999免费观看视频 | h片在线看 | 日韩高清一区 | 欧美激情国产日韩精品一区18 | 一区二区免费高清视频 | 91久久国产 | 国产成人精品久久 | 亚洲一区二区三区四区五区午夜 | 国产一级视频 | 国产小视频精品 | 国产美女自拍视频 | 九九热免费看 | 欧美日本在线观看 | 成人av鲁丝片一区二区小说 | 超碰成人免费观看 | 高清一区二区三区 | 超碰97免费观看 | 综合久久综合久久 | 99热碰| 九九视频在线观看视频6 |