Spring中AOP注解@Aspect的使用詳解
AOP思想
AOP(Aspect Oriented Programming)是一種面向切面的編程思想。面向切面編程是將程序抽象成各個(gè)切面,即解剖對(duì)象的內(nèi)部,將那些影響了多個(gè)類的公共行為抽取到一個(gè)可重用模塊里,減少系統(tǒng)的重復(fù)代碼,降低模塊間的耦合度,增強(qiáng)代碼的可操作性和可維護(hù)性。AOP把軟件系統(tǒng)分為兩個(gè)部分:核心關(guān)注點(diǎn)和橫切關(guān)注點(diǎn)。業(yè)務(wù)處理的主要流程是核心關(guān)注點(diǎn),與之關(guān)系不大的部分是橫切關(guān)注點(diǎn)。橫切關(guān)注點(diǎn)的一個(gè)特點(diǎn)是,他們經(jīng)常發(fā)生在核心關(guān)注點(diǎn)的多處,而各處都基本相似。比如權(quán)限認(rèn)證、日志、事務(wù)處理、增強(qiáng)處理。
AOP的使用場景
權(quán)限認(rèn)證、日志、事務(wù)處理、增強(qiáng)處理
@Aspect的使用以及基本概念
1.切面類 @Aspect: 定義切面類,加上@Aspect、@Component注解
@Aspect @Component //設(shè)置注解執(zhí)行的順序 @Order(2) public class AnnotationAspectTest
2.切點(diǎn) @Pointcut
/**
* 定義切點(diǎn),切點(diǎn)為對(duì)應(yīng)controller
*/
@Pointcut("execution(public * com.example.zcs.Aop.controller.*.*(..))")
public void aopPointCut(){
}注:execution表達(dá)式第一個(gè)*表示匹配任意的方法返回值,第二個(gè)*表示所有controller包下的類,第三個(gè)*表示所有方法,第一個(gè)..表示任意參數(shù)個(gè)數(shù)。
3.Advice,在切入點(diǎn)上執(zhí)行的增強(qiáng)處理,主要有五個(gè)注解:
@Before 在切點(diǎn)方法之前執(zhí)行
@After 在切點(diǎn)方法之后執(zhí)行
@AfterReturning 切點(diǎn)方法返回后執(zhí)行
@AfterThrowing 切點(diǎn)方法拋異常執(zhí)行
@Around 屬于環(huán)繞增強(qiáng),能控制切點(diǎn)執(zhí)行前,執(zhí)行后
4.JoinPoint :方法中的參數(shù)JoinPoint為連接點(diǎn)對(duì)象,它可以獲取當(dāng)前切入的方法的參數(shù)、代理類等信息,因此可以記錄一些信息,驗(yàn)證一些信息等;
5.使用&&、||、!、三種運(yùn)算符來組合切點(diǎn)表達(dá)式,表示與或非的關(guān)系;
6.@annotation(annotationType) 匹配指定注解為切入點(diǎn)的方法;
具體代碼實(shí)現(xiàn)
1.AopController,用于校驗(yàn)aop是否生效:
@Controller
@RequestMapping("aop")
public class AopController {
@RequestMapping("test")
@ResponseBody
public String aopTest(User user) {
// System.out.println(user);
System.out.println("aop測試");
return "success";
}
@TestAnnotation(flag = false)
@RequestMapping("aopAnnotationTest")
@ResponseBody
public String aopAnnotationTest(User user) {
// System.out.println(user);
System.out.println("aopAnnotationTest");
return "success";
}
}2.AspectTest,具體的切面類,用于添加橫切邏輯,切點(diǎn)使用execution表達(dá)式進(jìn)行匹配
@Aspect
@Component
//設(shè)置注解執(zhí)行的順序
@Order(1)
public class AspectTest {
/**
* 定義切點(diǎn),切點(diǎn)為對(duì)應(yīng)controller
*/
@Pointcut("execution(public * com.example.zcs.Aop.controller.*.*(..))")
public void aopPointCut(){
}
@Before("aopPointCut()")
public void testbefor(JoinPoint joinPoint) {
illegalParam(joinPoint);
System.out.println("執(zhí)行方法之前執(zhí)行。。。。。");
}
@After("aopPointCut()")
public void testAfter(JoinPoint joinPoint) {
//illegalParam(joinPoint);
System.out.println("執(zhí)行方法之后執(zhí)行。。。。。");
}
/**
*獲取請求參數(shù)
* @param joinPoint
* @return
*/
private static void illegalParam(JoinPoint joinPoint) {
if(joinPoint == null){
return;
}
boolean flag = false;
try{
// 參數(shù)值
Object[] args = joinPoint.getArgs();
if (args != null) {
for (Object o : args) {
System.out.println(o);
}
}
}catch(Exception e){
}
}
}3.AnnotationAspectTest類,具體的切面類,用于添加橫切邏輯,切點(diǎn)指定注解
@Aspect
@Component
//設(shè)置注解執(zhí)行的順序
@Order(2)
public class AnnotationAspectTest {
/**
* 定義切點(diǎn),切點(diǎn)為添加了注解的方法
*/
@Pointcut("@annotation(com.example.zcs.Aop.annotation.TestAnnotation)")
public void aopPointCut(){
}
@Around("aopPointCut()")
public Object Around(ProceedingJoinPoint point) throws Throwable {
System.out.println("AnnotationAspectTest Around start ");
//獲取注解和注解的值
TestAnnotation annotation = getAnnotation(point);
if (annotation != null) {
boolean flag = annotation.flag();
System.out.println("注解flags的值:" + flag);
}
//獲取參數(shù)
Object[] args = point.getArgs();
for (Object arg : args) {
System.out.println("arg ==>" + arg);
}
//去調(diào)用被攔截的方法
Object proceed = point.proceed();
return proceed;
}
//獲取注解
public TestAnnotation getAnnotation(ProceedingJoinPoint point) {
Signature signature = point.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
if (method != null){
return method.getAnnotation(TestAnnotation.class);
}
return null;
}
}4.注解類TestAnnotation
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TestAnnotation {
boolean flag() default true;
}到此這篇關(guān)于Spring中AOP注解@Aspect的使用詳解的文章就介紹到這了,更多相關(guān)Spring的@Aspect注解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringMVC整合SpringSession 實(shí)現(xiàn)sessiong
這篇文章主要介紹了SpringMVC整合SpringSession 實(shí)現(xiàn)session的實(shí)例代碼,本文通過實(shí)例相結(jié)合的形式給大家介紹的非常詳細(xì),需要的朋友參考下吧2018-04-04
Java Testcontainers庫實(shí)現(xiàn)測試功能
這篇文章主要介紹了Java Testcontainers庫實(shí)現(xiàn)測試功能,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09
SpringBoot整合Hashids實(shí)現(xiàn)數(shù)據(jù)ID加密隱藏的全過程
這篇文章主要為大家詳細(xì)介紹了SpringBoot整合Hashids實(shí)現(xiàn)數(shù)據(jù)ID加密隱藏的全過程,文中的示例代碼講解詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-01-01
Java?Swing實(shí)現(xiàn)自定義按鈕組件的完整代碼
本文介紹了Java?Swing按鈕工具類,用于簡化按鈕創(chuàng)建,它封裝了多種按鈕樣式、圖標(biāo)及事件處理,支持懸停效果,開發(fā)者僅需一行代碼即可創(chuàng)建規(guī)范按鈕,大幅提升開發(fā)效率,文中附有完整源碼2026-05-05
使用Spring CROS解決項(xiàng)目中的跨域問題詳解
這篇文章主要介紹了使用Spring CROS解決項(xiàng)目中的跨域問題詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01
Java concurrency線程池之線程池原理(一)_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了Java concurrency線程池之線程池原理,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
SpringBoot項(xiàng)目如何修改Tomcat版本號(hào)
本文介紹了Spring Boot項(xiàng)目默認(rèn)使用內(nèi)嵌Tomcat Servlet容器打包部署,通過添加指定版本的Tomcat GA依賴,可以修改默認(rèn)版本號(hào),對(duì)于jar包和war包形式的部署,無需排除內(nèi)置Tomcat,此經(jīng)驗(yàn)為個(gè)人見解,僅供參考2026-04-04

