一、Spring Execution概述
Spring Execution是Spring框架提供的一個用於執行方法的工具,它提供了豐富的AOP功能。Spring框架的AOP模塊通過代理技術實現,將方法調用轉化為對代理對象的調用,並在代理對象的方法中進行前置、後置、異常和返回通知等操作,從而實現對目標方法的增強。Spring Execution正是在這個過程中扮演了重要的角色,是實現AOP的關鍵之一。
二、Spring Execution常用註解
@Pointcut
在Spring Execution中,@Pointcut用於定義切點,表示哪些方法需要被增強。@Pointcut註解的值是一個String類型,表示一個切點表達式,用於匹配目標方法。以下是一個示例:
@Pointcut("execution(* com.example.demo.service..*.*(..))")
public void servicePointcut() {}
上述示例中,切點表達式匹配com.example.demo.service包中的所有方法,包括其子包中的所有方法。
@Before
@Before用於在目標方法執行前執行增強操作。示例如下:
@Before("servicePointcut()")
public void beforeAdvice(JoinPoint joinPoint) {
System.out.println("Before advice for " + joinPoint.getSignature().getName());
}
上述示例中,beforeAdvice方法在servicePointcut匹配的方法執行前被執行,輸出目標方法的名稱。
@AfterReturning
@AfterReturning用於在目標方法正常返回後執行增強操作。以下是一個示例:
@AfterReturning(pointcut = "servicePointcut()", returning = "result")
public void afterReturningAdvice(JoinPoint joinPoint, Object result) {
System.out.println("After returning advice for " + joinPoint.getSignature().getName() + ", result=" + result);
}
上述示例中,afterReturningAdvice方法在servicePointcut匹配的方法正常返回後被執行,輸出目標方法的名稱和返回值。
@AfterThrowing
@AfterThrowing用於在目標方法拋出異常後執行增強操作。以下是一個示例:
@AfterThrowing(pointcut = "servicePointcut()", throwing = "ex")
public void afterThrowingAdvice(JoinPoint joinPoint, Exception ex) {
System.out.println("After throwing advice for " + joinPoint.getSignature().getName() + ", exception=" + ex.getMessage());
}
上述示例中,afterThrowingAdvice方法在servicePointcut匹配的方法拋出異常後被執行,輸出目標方法的名稱和異常信息。
@After
@After用於在目標方法執行完成後執行增強操作,無論目標方法是正常返回還是拋出異常。以下是一個示例:
@After("servicePointcut()")
public void afterAdvice(JoinPoint joinPoint) {
System.out.println("After advice for " + joinPoint.getSignature().getName());
}
上述示例中,afterAdvice方法在servicePointcut匹配的方法執行完成後被執行,輸出目標方法的名稱。
三、Spring Execution使用示例
以下是一個簡單的示例,演示如何使用Spring Execution進行增強:
@Service
public class SampleService {
public void sampleMethod(String param) throws Exception {
System.out.println("Executing sampleMethod with param " + param);
if (param == null) {
throw new Exception("param cannot be null");
}
}
}
@Aspect
@Component
public class SampleAspect {
@Pointcut("execution(* com.example.demo.service.SampleService.sampleMethod(..)) && args(param)")
public void samplePointcut(String param) {}
@Before("samplePointcut(param)")
public void beforeAdvice(String param) {
System.out.println("Before advice for sampleMethod with param " + param);
}
@AfterThrowing(pointcut = "samplePointcut(param)", throwing = "ex")
public void afterThrowingAdvice(String param, Exception ex) {
System.out.println("After throwing advice for sampleMethod with param " + param + ", exception=" + ex.getMessage());
}
}
@RestController
public class SampleController {
@Autowired
private SampleService sampleService;
@GetMapping("/sample")
public String sampleMethod(@RequestParam(required = false) String param) throws Exception {
sampleService.sampleMethod(param);
return "success";
}
}
上述示例中,定義了一個SampleService類,其中包含一個sampleMethod方法,該方法接收一個參數,並可能拋出異常。通過定義SampleAspect類,使用@Before和@AfterThrowing註解分別增強了sampleMethod方法的前置和異常通知。在SampleController中,通過@Autowired注入了SampleService,並在/sample接口中調用了sampleMethod方法。如果/sample接口中未傳遞param參數,則會觸發異常,導致執行afterThrowingAdvice方法。
原創文章,作者:WBSA,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/136260.html