1. 什么是AOP?
AOP(Aspect Oriented Programming):面向切面編程。
面向切面編程是一種思想,其實(shí)就是對(duì)某一類事情進(jìn)行統(tǒng)一的處理。而 SpringAOP就是一種AOP的具體實(shí)現(xiàn)的框架。這就好比 IOC 和 DI 一樣的關(guān)系。
上述就是對(duì)登錄功能進(jìn)行了一個(gè)統(tǒng)一的處理!
2. AOP能用來(lái)干些什么?
除了上面的判斷登錄之外,還有:
- 統(tǒng)一日志記錄
- 統(tǒng)一的方法執(zhí)行時(shí)間統(tǒng)計(jì)
- 統(tǒng)一的返回格式設(shè)置
- 統(tǒng)一的異常處理
- 事務(wù)的開(kāi)啟和提交
3. 學(xué)習(xí)AOP
3.1 AOP的組成
3.1.1 切面(Aspect)
切面:定義的是事件,也就是AOP是用來(lái)做啥的。
例如:用來(lái)做用戶登錄校驗(yàn)
3.1.2 切點(diǎn)(Pointcut)
切點(diǎn):定義具體攔截規(guī)則。
例如:哪些接口需要判斷用戶登錄,哪些不需要
3.1.3 通知(Advice)
通知:定義AOP具體的執(zhí)行方法。
例如:從 Session 中獲取用戶信息,如果獲取到則是登錄,沒(méi)獲取到表示未登錄。
3.1.4 連接點(diǎn)(Jion Point)
連接點(diǎn):有可能觸發(fā)切點(diǎn)的所有點(diǎn),也就是所有接口。
3.2 SpringAOP實(shí)現(xiàn)
3.2.1 添加依賴
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
3.2.2 定義切面
@Aspect // 表示這個(gè)為切面
@Component
public class UserAspect {
}
上述中,@Aspect注解表示這個(gè)類為切面類。@Component表示這個(gè)類隨著SpringBoot啟動(dòng)而啟動(dòng)。
3.2.3 定義切點(diǎn)
@Aspect // 表示這個(gè)為切面
@Component
public class UserAspect {
// 定義切點(diǎn)
@Pointcut("execution(* com.example.springaop.controller.UserController.*(..))")
public void pointcut(){}
}
使用@Pointcut注解進(jìn)行定義切點(diǎn),格式為 :
excution(<修飾符><返回類型><包.類.?法(參數(shù))><異常>) ,一般修飾符和異??墒÷浴?/p>
3.2.4 執(zhí)行通知
@Aspect // 表示這個(gè)為切面
@Component
public class UserAspect {
// 定義切點(diǎn)
@Pointcut("execution(* com.example.springaop.controller.UserController.*(..))")
public void pointcut(){}
// 前置通知
@Before("pointcut()")
public void doBefore(){
System.out.println("執(zhí)行了前置通知");
}
// 后置通知
@After("pointcut()")
public void doAfter(){
System.out.println("執(zhí)行了后置通知");
}
// 返回之后通知
@AfterReturning(value = "pointcut()",returning = "")
public void doAfterReturning(){
System.out.println("執(zhí)行了返回之后通知");
}
// 異常通知
@AfterThrowing("pointcut()")
public void doAfterThrowing(){
System.out.println("執(zhí)行了異常通知");
}
// 環(huán)繞通知
@Around("pointcut()")
public Object doAroud(ProceedingJoinPoint joinPoint){
Object result = null;
System.out.println("環(huán)繞通知執(zhí)行之前");
try {
// 執(zhí)行目標(biāo)方法
result = joinPoint.proceed();
} catch (Throwable e) {
throw new RuntimeException(e);
}
System.out.println("環(huán)繞通知執(zhí)行之后");
return result;
}
}
可以通過(guò)下面看到執(zhí)行順序:
4. SpringAOP實(shí)現(xiàn)原理
SpringAOP是構(gòu)建在動(dòng)態(tài)代理的基礎(chǔ)上實(shí)現(xiàn)的,因此 Spring 對(duì) AOP 支持局限于方法級(jí)別上。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-645253.html
- JDK Proxy:默認(rèn)情況下,實(shí)現(xiàn)了接口的類,使用 AOP 基于 JDK 生成代理類
- CGLIB:默認(rèn)情況下,沒(méi)有實(shí)現(xiàn)接口的類,通過(guò)實(shí)現(xiàn)代理類的子類來(lái)實(shí)現(xiàn)動(dòng)態(tài)代理(被final修飾的類不能代理)
- 兩者底層都是通過(guò)反射
JDK 和 CGLIB 區(qū)別:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-645253.html
- JDK來(lái)自JAVA;CGLIB屬于三方
- JDK:是通過(guò)實(shí)現(xiàn)類接口的類來(lái)生成代理類;CGLIB是通過(guò)實(shí)現(xiàn)了代理類的子類來(lái)實(shí)現(xiàn)動(dòng)態(tài)地理
- JDK7之后版本,JDK Proxy性能高于 CGLIB;JDK7之前,CGLIB 性能遠(yuǎn)遠(yuǎn)高于 JDK Proxy
到了這里,關(guān)于一文帶你迅速了解下Spring中的AOP的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!