springboot
<dependency><!-- AOP -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
AOP
package com.cy.myblog.controller.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Aspect
@Component
public class SysLogAspect {
@Pointcut("execution(* com.cy.myblog.service.*.*(..))")
public void doLog() {}
@Before("doLog()")
public void doBefore() {
log.info("######### doBefore #########");
}
@Around("doLog()")
public Object doRound(ProceedingJoinPoint jp ) throws Throwable {
try {
log.info("######### doRound - before #########");
Object result = jp.proceed();
log.info("######### doRound - after #########");
return result ;
} catch (Throwable e) {
log.info("######### doRound - exception #########");
throw e ;
} finally {
log.info("######### doRound - finally #########");
}
}
@After("doLog()")
public void doAfter() {
log.info("######### doAfter #########");
}
@AfterReturning(pointcut = "doLog()" , returning = "result")
public Object doAfterReturn(Object result) {
log.info("######### doAfterReturn:resutl=[{}] #########", result);
return result ;
}
@AfterThrowing(pointcut = "doLog()" , throwing = "e")
public void doAfterThrowing(Exception e) {
log.info("######### doAfterThrowing:exception=[{}] #########", e.getMessage());
}
}
AOP 概念
-
通知(Advice)
指切面(定义为aspect的类)中的工作; -
spring切面可以应用的五种通知:
- 前置通知(Before):在目标方法被调用之前调用通知功能;
- 后置通知(After):在目标方法完成之后调用通知,此时不会关心方法的输出是什么;
- 返回通知(After-returning):在目标方法成功执行之后调用通知;
- 异常通知(After-throwing):在目标方法抛出异常后调用通知;
- 环绕通知(Around):通知报过了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为。
-
连接点(Join point)
连接点是在应用执行过程中能够插入切面的一个点。这个点可以是调用方法时,抛出异常时,甚至修改一个字段时。切面代码可以利用这些点插入到应用的正常流程之中,并添加新的行为。(切点方法中配置的匹配的方法都是连接点) -
切点(Pointcut)
定义通知所要织入的一个或多个连接点。 -
切面(Aspect)
是通知和切点的结合。
切面获取请求信息
如果要获取 request 或者 response
@GetMapping(value = "")
public String center() {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletRequest request = servletRequestAttributes.getRequest();
HttpServletResponse response = servletRequestAttributes.getResponse();
//...
}