1、簡(jiǎn)介
-
AOP即面向切面編程Aspect Oriented Program。
- 面向切面編程將系統(tǒng)功能分為核心業(yè)務(wù)功能和切面功能,核心業(yè)務(wù)功能主要是注冊(cè)登錄、數(shù)據(jù)庫(kù)操作等,切面功能主要有日志、權(quán)限、性能分析等。
- AOP將與核心功能一起調(diào)用的任務(wù)和邏輯分離開(kāi)并封裝起來(lái),有助于減少系統(tǒng)的重復(fù)代碼,降低模塊間的耦合度。
2、AOP中的概念
- 切點(diǎn)(PointCut):指定切入的類(lèi)或方法(
)
- 通知(Advice):對(duì)方法在什么時(shí)間(
)需要執(zhí)行的操作(
)
- 切面(Aspect):切點(diǎn)+通知
- 織入(Weaving):將切面加入到對(duì)象中,并創(chuàng)建代理的過(guò)程。
3、AOP的通知類(lèi)型
- before(前置通知):在方法開(kāi)始執(zhí)行前執(zhí)行
- after(后置通知): 在方法執(zhí)行后執(zhí)行
- afterReturning(返回后通知): 在方法返回后執(zhí)行
- afterThrowing(異常通知): 在拋出異常時(shí)執(zhí)行
- around(環(huán)繞通知): 在方法執(zhí)行前和執(zhí)行后都會(huì)執(zhí)行
4、快速入門(mén)
- 構(gòu)建spring boot項(xiàng)目
- 引入AOP依賴(lài)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
- 創(chuàng)建一個(gè)service類(lèi)
public class Calculator {
public int divide(int a, int b) {
System.out.println("除法:" + a + "/" + b);
return a / b;
}
public int add(int a, int b) {
System.out.println("加法:" + a + "+" + b);
return a + b;
}
}
@Aspect
public class CalculatorAop {
//切點(diǎn) Calculator的+-*/方法
@Pointcut("execution(public int com.samllbear.aopdemo.service.Calculator.divide(..))")
public void pointCut() {}
@Before("pointCut()")
public void before(JoinPoint joinPoint) {
System.out.println("Before...");
Signature signature = joinPoint.getSignature(); // 獲取方法的簽名
System.out.println("執(zhí)行運(yùn)算:" + signature.getName()); // 獲取方法名稱(chēng)
System.out.println("執(zhí)行參數(shù):" + Arrays.toString(joinPoint.getArgs())); // 方法參數(shù)
}
@After("pointCut()")
public void after() {
System.out.println("After...");
}
@AfterReturning(value = "pointCut()", returning = "result")
public void afterReturning(Object result) {
System.out.println("Returning...");
System.out.println("執(zhí)行結(jié)果:" + result);
}
@AfterThrowing(value = "pointCut()", throwing = "exception")
public void afterThrowing(Exception exception) {
System.out.println("Throwing...");
System.out.println(exception.getMessage());
}
}
@Configuration
@EnableAspectJAutoProxy // 開(kāi)啟aop
public class CalculatorConfig {
@Bean // 注入計(jì)算器
public Calculator calculator() {
return new Calculator();
}
@Bean // 注入aop
public CalculatorAop calculatorAop() {
return new CalculatorAop();
}
}
class AopDemoApplicationTests {
@Test
public void divideTest() {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(CalculatorConfig.class);
// 注意只有注入容器的bean AOP才會(huì)生效
Calculator calculator = context.getBean(Calculator.class);
// calculator.divide(13, 0); // throwing... /By Zero
calculator.divide(13, 2);
}
}
Before...
執(zhí)行運(yùn)算:divide
執(zhí)行參數(shù):[13, 2]
除法:13/2
After...
Returning...
執(zhí)行結(jié)果:6
- 環(huán)繞通知(Around)可以用來(lái)替換以上四種通知
在CalculatorAop.class添加以下代碼
private static final Logger log = LoggerFactory.getLogger(CalculatorAop.class);
@Pointcut("execution(public int com.samllbear.aopdemo.service.Calculator.add(..))")
public void addPointCut() {}
@Around("addPointCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
try {
System.out.println("around begin...");
Object o = joinPoint.proceed(); // 執(zhí)行目標(biāo)方法
System.out.println("around end...");
return o;
} catch (Throwable e) {
System.out.println("around throwing...");
log.error(e.getMessage());
throw e;
} finally {
System.out.println("around returning...");
}
}
@Test
public void addTest() {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(CalculatorConfig.class);
Calculator calculator = context.getBean(Calculator.class);
calculator.add(13, 0);
}
around begin...
加法:13+0
around end...
around returning...
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。