aop后置切面获取返回值
时间: 2023-07-01 13:09:46 浏览: 175
在 AOP 后置切面中获取返回值,可以通过 `JoinPoint` 参数中的 `getArgs()` 方法获取方法的参数列表,然后通过 `ProceedingJoinPoint` 接口的 `proceed()` 方法执行目标方法,并获取目标方法的返回值。以下是一个示例代码:
```java
@Aspect
@Component
public class MyAspect {
@AfterReturning(value = "execution(* com.example.demo.service.UserService.getUserById(..))", returning = "result")
public void afterReturning(JoinPoint joinPoint, Object result) {
System.out.println("方法返回值:" + result.toString());
}
}
```
在上面的代码中,`@AfterReturning` 注解指定了切点表达式和返回值参数名 `result`。在方法执行完毕后,可以通过 `result` 参数获取方法的返回值。
相关问题
实现一下aop切面存储操作日志,并且解释每一行代码的意思
好的,下面是一个简单的示例,演示如何使用 AOP 实现切面存储操作日志:
```java
@Aspect
@Component
public class LogAspect {
private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);
@Autowired
private HttpServletRequest request;
@Pointcut("execution(public * com.example.controller.*.*(..))")
public void controllerLog() {}
@Before("controllerLog()")
public void doBefore(JoinPoint joinPoint) {
logger.info("Request URL : {} {}", request.getRequestURL().toString(), request.getMethod());
logger.info("IP : {}", request.getRemoteAddr());
logger.info("Class Method : {}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
logger.info("Args : {}", Arrays.toString(joinPoint.getArgs()));
}
@AfterReturning(returning = "result", pointcut = "controllerLog()")
public void doAfterReturning(Object result) {
logger.info("Response : {}", result);
}
}
```
代码解释:
- `@Aspect` 注解表示这是一个切面类。
- `@Component` 注解表示让 Spring 自动扫描并注册该组件。
- `private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);` 声明一个日志记录器。
- `@Autowired private HttpServletRequest request;` 注入 HttpServletRequest 对象,以便获取请求信息。
- `@Pointcut("execution(public * com.example.controller.*.*(..))")` 定义切点,表示匹配 com.example.controller 包下的所有公共方法。
- `@Before("controllerLog()")` 定义前置通知,表示在切点方法执行前执行该方法。
- `JoinPoint` 是 Spring AOP 提供的用于获取连接点信息的类,可以获取方法名、参数等信息。
- `@AfterReturning(returning = "result", pointcut = "controllerLog()")` 定义后置通知,表示在切点方法执行后执行该方法。
- `returning = "result"` 表示将方法的返回值赋值给 result 参数。
- `logger.info()` 是日志记录器的方法,用于记录日志信息。
以上代码实现了一个简单的 AOP 切面,用于记录 controller 的操作日志。在具体的业务场景中,可以根据实际需要进行扩展和定制。
@Around("execution(void com.itheima.service.impl.DeptServiceImpl.findAll())") public Object m2(ProceedingJoinPoint pjp) { Object obj = null; //前置通知 System.out.println("1.进入目标方法之前执行"); try { //执行被代理的方法 obj = pjp.proceed(); //后置通知 System.out.println("2.执行目标方法获取返回值之后"); } catch (Throwable e) { //异常通知 System.out.println("3.方法抛出异常之后执行"); } finally { // 最终通知 System.out.println("4.最终通知:无论是否抛出异常都会执行(finally)"); } return obj; }运行流程及原理详解
这段代码是一个AOP(面向切面编程)的示例。它定义了一个切面类,使用了Spring AOP框架的注解来定义切点和通知类型。
具体运行流程如下:
1. 在DeptServiceImpl的findAll方法执行前,AOP框架会先执行m2方法中的前置通知,即输出“1.进入目标方法之前执行”。
2. 然后,AOP框架会调用被代理的findAll方法,获取返回值。
3. 在findAll方法执行完毕后,AOP框架会执行m2方法中的后置通知,即输出“2.执行目标方法获取返回值之后”。
4. 如果findAll方法执行过程中发生了异常,AOP框架会执行m2方法中的异常通知,即输出“3.方法抛出异常之后执行”。
5. 无论findAll方法是否抛出异常,AOP框架都会执行m2方法中的最终通知,即输出“4.最终通知:无论是否抛出异常都会执行(finally)”。
这种方式可以实现对目标方法的拦截和增强,比如在方法执行前后打印日志、记录方法执行时间等。原理是使用动态代理,在运行时生成代理对象,在代理对象中插入切面逻辑,从而实现对目标方法的拦截和增强。
阅读全文