本篇內(nèi)容主要講解“SpringAOP的注解方式是什么”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“SpringAOP的注解方式是什么”吧!
網(wǎng)站的建設(shè)創(chuàng)新互聯(lián)專(zhuān)注網(wǎng)站定制,經(jīng)驗(yàn)豐富,不做模板,主營(yíng)網(wǎng)站定制開(kāi)發(fā).小程序定制開(kāi)發(fā),H5頁(yè)面制作!給你煥然一新的設(shè)計(jì)體驗(yàn)!已為履帶攪拌車(chē)等企業(yè)提供專(zhuān)業(yè)服務(wù)。
SpringAOP不是一門(mén)技術(shù)而是一種設(shè)計(jì)思想,稱(chēng)為面向切面編程,是利用橫切技術(shù)剖析對(duì)象內(nèi)部,將業(yè)務(wù)之間共同調(diào)用的邏輯提取并封裝為一個(gè)可復(fù)用的模塊,這個(gè)模塊被命名為切面(Aspect),該模塊減少系統(tǒng)中的重復(fù)代碼,降低模塊間的耦合度,可用于日志、權(quán)限認(rèn)證、事務(wù)管理等
AOP是基于代理實(shí)現(xiàn)的,Java默認(rèn)采用的是JDK動(dòng)態(tài)代理,但是JDK動(dòng)態(tài)代理只能代理接口不能代理類(lèi)。因此springAOP會(huì)在JDK動(dòng)態(tài)代理和CGLIB代理之間進(jìn)行動(dòng)態(tài)切換。
動(dòng)態(tài)代理:在運(yùn)行時(shí)借助于JDk動(dòng)態(tài)代理、CGLIB等再內(nèi)存中臨時(shí)臨時(shí)生成AOP代理類(lèi),也被成為運(yùn)行時(shí)增強(qiáng)
靜態(tài)代理:指使用AOP框架的命令進(jìn)行編譯,從而在編譯階段就可以生成AOP代理類(lèi),也被成為編譯增強(qiáng)
代理目標(biāo)對(duì)象實(shí)現(xiàn)了接口,默認(rèn)采用JDK動(dòng)態(tài)代理,也可以強(qiáng)制使用CGLIB
代理目標(biāo)對(duì)象沒(méi)有實(shí)現(xiàn)接口,必須使用CGLIB
Spring會(huì)自動(dòng)在JDK動(dòng)態(tài)代理和CGLIB代理直接轉(zhuǎn)換
切面(Aspect):切面是通知和切點(diǎn)的結(jié)合,通知和切點(diǎn)共同定義了切面的全部?jī)?nèi)容。
通知(Advice):定義了切面何時(shí)使用,通知分為以下幾種類(lèi)型
前置通知(Before):在目標(biāo)方法被調(diào)用之前調(diào)用通知功能
后置通知(After):在目標(biāo)方法執(zhí)行完成之后調(diào)用通知,此時(shí)不會(huì)關(guān)心方法的輸出是什么
返回通知(After-returning):在目標(biāo)方法成功執(zhí)行之后調(diào)用通知
異常通知(After-throwing):在目標(biāo)方法拋出異常后調(diào)用通知
環(huán)繞通知(Around):在被通知的方法調(diào)用之前和調(diào)用之后執(zhí)行自定義的行為
切點(diǎn)(PointCut):定義了在何處應(yīng)用連接點(diǎn),通常明確使用在類(lèi)和方式名稱(chēng)上,或者使用正在匹配或者注解方式
連接點(diǎn)(JoinPoin):連接點(diǎn)是在應(yīng)用程序運(yùn)行中能夠插入切面的一個(gè)點(diǎn),具體插入方式根據(jù)通知的不同而不同
目標(biāo)對(duì)象(Target): 需要被搭理的對(duì)象,由切點(diǎn)定義出來(lái)的
織入(Weaving):把切面應(yīng)用到目標(biāo)對(duì)象并創(chuàng)建新的代理對(duì)象的過(guò)程
編譯時(shí)織入
類(lèi)加載時(shí)織入
運(yùn)行時(shí)織入
博主以日志收集為例演示注解方式的實(shí)現(xiàn)
org.springframework.boot spring-boot-starter-aop
import java.lang.annotation.*;/** * 日志注解 * * @author chilx */@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface LogAnnotation { /** * 方法名稱(chēng) */String title() default "";/** * 操作類(lèi)型 {@link LogTypeConsts} */String type() default "";/** * 操作描述 */String remark() default "";}
import com.chilx.aop.annotation.LogAnnotation;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.*;import org.springframework.stereotype.Component;/** * @author chilx * @date 2021/3/31 **/@Aspect@Componentpublic class LogAnnotationAspect { /** * 切點(diǎn) */@Pointcut("@annotation(com.chilx.aop.annotation.LogAnnotation)")public void logPointCut() { }/** * 前置通知: 方法執(zhí)行前調(diào)用 * 注意: 在配置value:的時(shí)候可以使用@Annotation(參數(shù)名稱(chēng))的方式來(lái)使用我們自定的注解 * 切記前后的參數(shù)名稱(chēng)要一致 */@Before(value = "logPointCut() && @annotation(logInfo)", argNames = "point,logInfo")public void before(JoinPoint point, LogAnnotation logInfo) { // 參數(shù)Object[] args = point.getArgs();System.out.println();System.out.println("前置通知" + "-->" + logInfo.title() + "--" + logInfo.remark());}/** * 后置通知: 方法執(zhí)行后調(diào)用,若方法出現(xiàn)異常,不執(zhí)行 */@After(value = "logPointCut() && @annotation(logInfo)", argNames = "point,logInfo")public void after(JoinPoint point, LogAnnotation logInfo) { System.out.println("后置通知" + "-->" + logInfo.title() + "--" + logInfo.remark());}/** * 返回: 方法執(zhí)行后調(diào)用,若方法出現(xiàn)異常,不執(zhí)行 */@AfterReturning(value = "logPointCut() && @annotation(logInfo)", argNames = "point,logInfo")public void afterReturning(JoinPoint point, LogAnnotation logInfo) { System.out.println("后置通知" + "-->" + logInfo.title() + "--" + logInfo.remark());}/** * 環(huán)繞通知: */@Around(value = "logPointCut() && @annotation(logInfo)", argNames = "point,logInfo")public void around(ProceedingJoinPoint point, LogAnnotation logInfo) throws Throwable { System.out.println("執(zhí)行方法前");Object proceed = point.proceed(point.getArgs());System.out.println("執(zhí)行方法后");System.out.println("環(huán)繞通知" + "-->" + logInfo.title() + "--" + logInfo.remark());}/** * 異常通知:方法拋出異常時(shí)執(zhí)行 */@AfterThrowing(value = "logPointCut() && @annotation(logInfo)", argNames = "point,logInfo,e", throwing = "e")public void afterThrowing(JoinPoint point, LogAnnotation logInfo, Exception e) { System.out.println("異常通知" + "-->" + logInfo.title() + "--" + logInfo.remark());System.out.println(e.getMessage());}}
1、對(duì)于環(huán)繞通知使用對(duì)象是 ProceedingJoinPoint
2、 在使用類(lèi)似以下方式時(shí),切記加粗部分的名稱(chēng)要完全一致
@Before(value = “l(fā)ogPointCut() && @annotation(logInfo)”, argNames = “point,logInfo”)
public void before(JoinPoint point, LogAnnotation logInfo) {}
到此,相信大家對(duì)“SpringAOP的注解方式是什么”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢(xún),關(guān)注我們,繼續(xù)學(xué)習(xí)!