springboot中使用aop

参考文章

最近接触到aop的使用,所以写点东西记录一下,虽然在spring mvc时代用过aop,但是毕竟大势已去,现在需要追赶潮流。

从各方面讲,差距都不是很大,只不过springboot 用的都是注解,可能更方便些。

以前印象中,springmvc的aop是可以用来实现事务和日志通知的,但是现在springboot对于事务的处理有了更好用的注解@Transactional,所以我们就简单的看看如何使用spring boot的aop去实现日志通知吧。

被切入的方法如下

@RestController
public class LogController {

    @RequestMapping("/first")
    public Object first(){
        System.out.println("进入first() 方法");
        return "first Controller";
    }

    @RequestMapping("/doError")
    public Object error(){
        return 1/0;
    }

}

整个日志切面的代码如下

package com.yubotao.sbaop.aop;


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;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/**
 * @Auther: yubt
 * @Description:  日志切面
 * @Date: Created in 16:52 2018/11/23
 * @Modified By:
 */
// @Aspect 作用是把当前类标识为一个切面供容器读取
@Aspect
@Component
public class LogAspect {
    // (..) 表示方法的参数,两个"."表示任何参数
    @Pointcut("execution(public * com.yubotao.sbaop.controller.LogController.first(..))")
    public void webLog(){
        System.out.println("切入方法打印日志");
    }

    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable{
        // 接收到请求,记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        // 记录下请求内容
        System.out.println("URL : " + request.getRequestURL().toString());
        System.out.println("HTTP_METHOD : " + request.getMethod());
        System.out.println("IP : " + request.getRemoteAddr());
        System.out.println("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        System.out.println("ARGS : " + Arrays.toString(joinPoint.getArgs()));
    }
    
	// returing中的值ret就是切入方法的返回值
    @AfterReturning(returning = "ret", pointcut = "webLog()")
    public void doAfterReturning(Object ret) throws Throwable {
        // 处理完请求,返回内容
        System.out.println("方法的返回值 : " + ret);
    }

    // 后置异常通知, 不能与@Around共用,否则会失效
    @Order(1)
    @AfterThrowing(pointcut = "execution(* com.yubotao.sbaop.controller.LogController.error(..))", throwing = "ex")
    public void throwsLogs(JoinPoint jp, Exception ex){
        System.out.println("方法异常时执行.....");
        System.out.println("异常为: " + ex);
    }

    // 后置最终通知, final增强,不管是抛出异常或者正常退出都会执行
    @After("webLog()")
    public void after(JoinPoint jp){
        System.out.println("方法最后执行.....");
    }

    // 环绕通知,环绕增强,相当于MethodInterceptor
    @Around("webLog()")
    public Object around(ProceedingJoinPoint pjp){
        System.out.println("方法环绕start......");
        try{
            Object o = pjp.proceed();
            System.out.println("方法环绕proceed,结果是:" + o);
            return o;
        }catch (Throwable e){
            e.printStackTrace();
            return null;
        }
    }

}

基本标注写的比较详细了,如果还是有些地方不是特别清楚的,建议去看参考文章,我这里就不重复劳动了。

另外,关于execution函数表达式的具体用法,推荐这篇文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值