SpringBoot集成AOP的代碼示例
1.什么是AOP?
AOP(Aspect Oriented Programming,面向切面編程)是一種編程范式,它旨在將橫切關注點(cross-cutting concerns)從應用程序的業(yè)務邏輯中分離出來。橫切關注點是那些在多個模塊中重復出現(xiàn)的功能,如日志記錄、性能監(jiān)控、事務管理、安全控制等。AOP允許開發(fā)者將這些關注點模塊化,并在不影響應用程序主要功能的情況下,將它們編織到應用程序的各個點上。
AOP的關鍵概念
- 切面(Aspect):封裝了橫切關注點的模塊。它描述了要執(zhí)行的附加行為以及該行為應該被應用到哪些連接點上。
- 連接點(Joinpoint):程序執(zhí)行過程中的某個點,如方法調(diào)用或異常拋出。
- 通知(Advice):切面在特定的連接點上執(zhí)行的動作,如“before”、“after”、“around”等。
- 切入點(Pointcut):匹配連接點的表達式,定義了切面的哪個部分會被應用到哪些連接點上。
- 目標對象(Target Object):被一個或多個切面所通知的對象。
- 代理(Proxy):由AOP框架創(chuàng)建的對象,用來攔截目標對象上的方法調(diào)用。
AOP的實現(xiàn)方式
AOP可以通過以下幾種方式實現(xiàn):
- 基于代理的AOP:
- JDK動態(tài)代理:適用于實現(xiàn)接口的情況,利用反射機制生成代理類。
- CGLIB:使用字節(jié)碼技術生成子類,適用于未實現(xiàn)接口的情況。
- 基于字節(jié)碼操作的AOP:
- AspectJ:在編譯期或運行期通過修改字節(jié)碼來實現(xiàn)切面的編織,可以更細粒度地控制切面的織入。
- 聲明式AOP:
- Spring AOP:使用XML配置或注解(如
@Aspect、@Before、@After、@Around等)來定義切面和切入點,然后在運行時通過動態(tài)代理實現(xiàn)切面的編織。
- Spring AOP:使用XML配置或注解(如
實現(xiàn)AOP的關鍵技術
- 動態(tài)代理:在運行時動態(tài)創(chuàng)建代理對象,代理對象在調(diào)用目標方法前后可以執(zhí)行額外的操作。
- 字節(jié)碼操作庫:如ASM、ByteBuddy等,用于生成或修改字節(jié)碼,實現(xiàn)在類的加載之前或運行時修改類的行為。
- 元數(shù)據(jù)驅(qū)動:使用注解或XML配置來定義切面、切入點和通知,便于配置和管理AOP的規(guī)則。
AOP的主要優(yōu)點是能夠減少業(yè)務邏輯中的重復代碼,提高代碼的模塊化程度,使得關注點更加集中,同時也提高了代碼的可維護性和可讀性。在實際應用中,AOP經(jīng)常被用于企業(yè)級應用開發(fā),如在Spring框架中廣泛使用。
2.代碼工程
實驗目標
采用@aspect注解來實現(xiàn)aop
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springboot-demo</artifactId>
<groupId>com.et</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>aspect</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
</dependencies>
</project>
controller
package com.et.aspect.controller;
import com.et.aspect.service.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
public class HelloWorldController {
@Autowired
TestService testService;
@RequestMapping("/hello")
public Map<String, Object> showHelloWorld(){
Map<String, Object> map = new HashMap<>();
String str= testService.sayHello("liming");
map.put("msg",str);
return map;
}
}
service
package com.et.aspect.service;
public interface TestService {
public String sayHello(String name) ;
}
package com.et.aspect.service.impl;
import com.et.aspect.service.TestService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* @author liuhaihua
* @version 1.0
* @ClassName TestServiceImpl
* @Description todo
* @date 2024/09/05/ 9:21
*/
@Service
@Slf4j
public class TestServiceImpl implements TestService {
@Override
public String sayHello(String name) {
String sss="hello,"+name;
log.info(sss);
return sss;
}
}
aspect
@Aspect:作用是把當前類標識為一個切面供容器讀取
@Pointcut:定義切入點,Pointcut是植入Advice的觸發(fā)條件。 每個Pointcut的定義包括2部分,一是表達式,二是方法簽名。方法簽名必須是 public及void型。 可以將Pointcut中的方法看作是一個被Advice引用的助記符,因為表達式不直觀,因此我們可以通過方法簽名的方式為 此表達式命名。 因此Pointcut中的方法只需要方法簽名,而不需要在方法體內(nèi)編寫實際代碼。
@Around:環(huán)繞增強,相當于MethodInterceptor(方法攔截器)
@AfterReturning:后置增強,相當于AfterReturningAdvice,方法正常退出時執(zhí)行
@Before:標識一個前置增強方法,相當于BeforeAdvice的功能,相似功能的還有
@AfterThrowing:異常拋出增強,相當于ThrowsAdvice(異常通知)
@After: final增強,不管是拋出異?;蛘哒M顺龆紩?zhí)行
@Pointcut("execution(* com.et.aspect.service..*.*(..))")
public void aopPoint() {
}
@Before("aopPoint()")
public void doBefore(JoinPoint point) throws Throwable {
log.info("before ....");
}
@After("aopPoint()")
public void doAfter(JoinPoint point) throws Throwable {
log.info("after ....");
}
以上只是一些關鍵代碼,所有代碼請參見下面代碼倉庫
代碼倉庫
3.測試
啟動Spring Boot應用程序
訪問http://127.0.0.1:8088/hello
查看日志如下
2024-09-05 21:52:12.926 INFO 51009 --- [nio-8088-exec-1] com.et.aspect.aspect.TaskAspect : before .... 2024-09-05 21:52:12.939 INFO 51009 --- [nio-8088-exec-1] c.e.aspect.service.impl.TestServiceImpl : hello,liming 2024-09-05 21:52:12.939 INFO 51009 --- [nio-8088-exec-1] com.et.aspect.aspect.TaskAspect : after ....
以上就是Spring Boot集成AOP的代碼示例的詳細內(nèi)容,更多關于Spring Boot集成AOP的資料請關注腳本之家其它相關文章!
相關文章
Spring\SpringBoot配置連接數(shù)據(jù)庫的方法
最近在學習SpringBoot,第一步就是要配置數(shù)據(jù)庫,本文詳細的介紹了Spring\SpringBoot配置連接數(shù)據(jù)庫的方法,有需要的朋友們下面隨著小編來一起學習學習吧2021-06-06
Spring中網(wǎng)絡請求客戶端WebClient的使用詳解
作為替代,Spring 官方已在 Spring 5 中引入了 WebClient 作為非阻塞式 Reactive HTTP 客戶端,本文將通過樣例演示如何使用 WebClient,希望對大家有所幫助2024-04-04
基于String和List<String>間的相互轉(zhuǎn)換方式
這篇文章主要介紹了基于String和List間的相互轉(zhuǎn)換方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-05-05

