1. 程式人生 > >springboot配置aop切面詳解

springboot配置aop切面詳解

1 引入依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2  是否需要在程式主類中增加@EnableAspectJAutoProxy 註解

答案是否。只要引入了AOP依賴後,預設已經增加了@EnableAspectJAutoProxy。

3 例項

@Aspect
@Component
public class WebLogAspect {

    private Logger logger = Logger.getLogger(getClass());

    @Pointcut("execution(public * com.didispace.web..*.*(..))")
    public void webLog(){}

    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        // 接收到請求,記錄請求內容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        // 記錄下請求內容
        logger.info("URL : " + request.getRequestURL().toString());
        logger.info("HTTP_METHOD : " + 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 = "ret", pointcut = "webLog()")
    public void doAfterReturning(Object ret) throws Throwable {
        // 處理完請求,返回內容
        logger.info("RESPONSE : " + ret);
    }

}

注:doBefore也可以這樣寫,doBefore(ProceedingJoinPoint point),ProceedingJoinPoint 是JoinPoint實現子類且他倆都是介面。ProceedingJoinPoint是在JoinPoint的基礎上暴露出 proceed 這個方法。proceed很重要,這個是aop代理鏈執行的方法。暴露出這個方法,就能支援 aop:around 這種切面(而其他的幾種切面只需要用到JoinPoint,這跟切面型別有關), 能決定是否走代理鏈還是走自己攔截的其他邏輯。原文連結 http://blog.csdn.net/wabiaozia/article/details/79190142

防止二次代理

5 @Pointcut 組合使用,切入點之間可以通過 && || ! 邏輯表示式進入組合使用。 

@Pointcut("execution(public * com.didispace.web..*.*(..))")
    public void a1(){}
 @Pointcut("execution(public * com.didispace.web..*.*(..))")
    public void a2(){}
 @Before("a1||a2")
 public void doBefore(JoinPoint joinPoint) throws Throwable {。。。。。}

拓展:

指定類上包含註解的作為切點,然後可以在切入點開始處(如@Before @after)做具體的處理,如判斷是否標記了@service註解

@Pointcut("@annotation(com.aa.abc................)") 

包含指定註解的作為切點:所有標記了@ResponseBody 註解的作為切點

@Pointcut(value = "@annotation(org.springframework.web.bind.annotation.ResponseBody)")
public void responseBodyPointcut() {}

組合使用:指定類上,標註了指定註解的作為切點

6 指定代理方式jdk/cglib 在yml檔案配置

spring:
  aop:
    proxy-target-class: false #jdk

參考連結: