AOP具体的概念部分请参考:Spring AOP 面向切面编程入门
下面就是我写的一个简单的demo
在spring boot环境中仅需要在maven添加如下依赖即可:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
切点部分定义
该部分用Controller类举例:
package com.demo.AOPDemo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/AOP")
public class AOPController {
@RequestMapping("/test")
@ResponseBody
public String test(@RequestBody String body){
System.out.println("AOPController is executing");
return "AOP test";
}
@RequestMapping("/test2")
@ResponseBody
public String test2(@RequestBody String body){
System.out.println("AOPController is executing");
return "AOP test2";
}
@RequestMapping("/test3")
@ResponseBody
public String test(@RequestBody String body,String urlParam){
System.out.println("AOPController is executing");
return "AOP test3";
}
}
自定义AOP部分
package com.demo.AOPDemo;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
//自定义切面类
//@Aspect 注解 使之成为切面类
//@Component 注解 把切面类加入到IOC容器中
@Aspect
@Component
public class CustomizeAspect {
/**
*
* 通过@Pointcut注解声明频繁使用的切点表达式
* 切入点表达式的格式:execution([可见性]返回类型[声明类型].方法名(参数类型)[异常])
*
* @Order值越小,越先被执行。根据定义,该注解也可以被使用在class上
*/
//定义切入点,切入点为com.demo.AOPDemo.AOPController中的所有方法
/*@Pointcut("execution(public * com.demo.AOPDemo.AOPController.*(..)))")
public void CustomizeAspect() {
}*/
//@Pointcut("execution(public * com.demo.AOPDemo.AOPController.test(String)))")
@Order(2)
@Pointcut("execution(public * com.demo.AOPDemo.AOPController.test(String,String)))")
public void pointCutTest() {
}
@Order(1)
@Pointcut("execution(public * com.demo.AOPDemo.AOPController.test(String,String)))")
public void aroundPointCutTest() {
}
/**
* JoinPoint 封装有切点信息
*
* @description 在切点执行之前执行的通知
*/
//@Before("CustomizeAspect()&&args(body)")
//传参测试
@Before(value = "pointCutTest() && args(body,urlParam)")
public void doBeforeGame(JoinPoint joinPoint, String body, String urlParam) {
System.out.println("切点为:" + joinPoint.getSignature().getName());
System.out.println("传入参数为:" + body + " " + urlParam);
System.out.println("在切点执行之前执行的通知");
}
/**
* @description 在切点执行之后执行的通知(返回通知和异常通知的异常)
*/
//@After("CustomizeAspect()")
@After("pointCutTest()")
public void doAfterGame() {
System.out.println("在切点执行之后执行的通知(返回通知和异常通知的异常)");
}
/**
* @description 在切点执行之后执行的通知(返回通知)
*/
@AfterReturning("pointCutTest()")
public void doAfterReturningGame() {
System.out.println("在切点执行之后执行的通知");
}
/**
* @description 在切点执行之后执行的通知(异常通知)
*/
@AfterThrowing("pointCutTest()")
public void doAfterThrowingGame() {
System.out.println("在切点执行之后执行的异常通知");
}
/**
* 环绕通知接受ProceedingJoinPoint作为参数,它来调用被通知的方法。
* 通知方法中可以做任何的事情,当要将控制权交给被通知的方法时,需要调用ProceedingJoinPoint的proceed()方法。
* 当你不调用proceed()方法时,将会阻塞被通知方法的访问。
* <p>
* return result:用于返回被通知函数的返回值
*
* @description 使用环绕通知
*/
@Around("aroundPointCutTest()")
public Object doAroundGame(ProceedingJoinPoint pjp) throws Throwable {
Object result = new Object();
try {
System.out.println("环绕通知:在切点执行之前执行的通知");
result = pjp.proceed();
System.out.println("环绕通知:在切点执行之后执行的通知");
} catch (Throwable e) {
System.out.println("环绕通知:在切点执行之后执行的异常通知");
}
return result;
}
}
该示例简单演示了使用AOP如何传参,具体请参考Spring Aop 注解方式参数传递