目錄
- 前言
- 編程範式主要有以下幾類
- aop註解
- 用法
前言
spring提供兩個核心功能,一個是Ioc(控制反轉),另一個是Aop(面向切面編程),Ioc有助於應用對象之間的解耦,AOP則可以實現橫切關注點(如日誌、安全、緩存、重複提交和事務管理)與他們所影響的對象之間的解耦。
編程範式主要有以下幾類
- AOP(Aspect Oriented Programming)面向切面編程
- OOP(Object Oriented Programming)面向對象編程
- POP(procedure oriented programming)面向過程編程
- FP(Functional Programming)面向函數編程
aop註解
AOP主要包含了通知、切點和連接點燈術語,介紹如下:
- 通知(Advice)
通知定義了切面是什麼以及何時被調用,何時調用包含以下幾種:
- Before 在方法被調用之前調用通知
- After 在方法完成之後調用通知,無論方法執行是否成功
- After-returning 在方法成功執行之後調用通知
- After-throwing 在方法拋出異常後調用通知
- Around 通知包裹了被通知的方法,在被通知的方法調用之前和調用之後執行自定義的行爲
- 切點(PointCut)
通知定義了切面是什麼和何時被調用,切點定義了何處被調用,切點的定義會匹配通知所要織入的一個或多個連接點,我們通常使用明確的類的方法名稱來指定這些切點,或是利用正則表達式定義匹配的類和方法名稱來指定這些切點。
- 連接點(JoinPoint)
連接點是在應用執行過程中能夠插入切面的一個點,這個點可以是調用方法時,拋出異常時,甚至是修改一個字段時,切面代碼可以利用這些連接點插入到應用的正常流程中,並添加新的行爲,如日誌、安全、事務、緩存等。
-
@Aspect
: 切面,由通知和切入點共同組成,這個註解標註在類上表示爲一個切面。 -
@Joinpoint
: 連接點,被AOP攔截的類或者方法,在前置通知中有介紹使用@Joinpoint
獲取類名、方法、請求參數。 -
Advice
: 通知的幾種類型 -
@Before
: 前置通知,在某切入點@Pointcut
之前的通知 -
@After
: 後置通知,在某切入點@Pointcut
之後的通知無論成功或者異常。 -
@AfterReturning
: 返回後通知,方法執行return之後,可以對返回的數據做加工處理。 -
@Around
: 環繞通知,在方法的調用前、後執行。 -
@AfterThrowing
: 拋出異常通知,程序出錯跑出異常會執行該通知方法。 -
@Pointcut
: 切入點,從哪裏開始。例如從某個包開始或者某個包下的某個類等。
用法
AOP在spring中有兩種配置方式,一是xml配置的方式,二是自動註解的模式。
自動註解AOP
聲明切面類,包含註解@Aspect以及何時執行通知(Advice)
package com.ganji.demo.service.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Service;
/**
* Created by admin on 2015/9/2.
*/
@Aspect
@Service
public class XmlAopDemoUserLog {
// 配置切點 及要傳的參數
@Pointcut("execution(* com.ganji.demo.service.user.UserService.GetDemoUser(..)) && args(id)")
public void pointCut(int id)
{
}
// 配置連接點 方法開始執行時通知
@Before("pointCut(id)")
public void beforeLog(int id) {
System.out.println("開始執行前置通知 日誌記錄:"+id);
}
// 方法執行完後通知
@After("pointCut(id)")
public void afterLog(int id) {
System.out.println("開始執行後置通知 日誌記錄:"+id);
}
// 執行成功後通知
@AfterReturning("pointCut(id)")
public void afterReturningLog(int id) {
System.out.println("方法成功執行後通知 日誌記錄:"+id);
}
// 拋出異常後通知
@AfterThrowing("pointCut(id)")
public void afterThrowingLog(int id) {
System.out.println("方法拋出異常後執行通知 日誌記錄"+id);
}
// 環繞通知
@Around("pointCut(id)")
public Object aroundLog(ProceedingJoinPoint joinpoint,int id) {
Object result = null;
try {
System.out.println("環繞通知開始 日誌記錄"+id);
long start = System.currentTimeMillis();
//有返回參數 則需返回值
result = joinpoint.proceed();
long end = System.currentTimeMillis();
System.out.println("總共執行時長" + (end - start) + " 毫秒");
System.out.println("環繞通知結束 日誌記錄");
} catch (Throwable t) {
System.out.println("出現錯誤");
}
return result;
}
}
以上即實現aop。