springboot中整合aop切面,用于添加日志信息

    技术2022-07-11  92

    1.添加aop依赖

    <!--引入AOP依赖start 记录日志 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <!--AspectJ --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.6.11</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.6.11</version> </dependency> <!-- cglib代理--> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.1</version> </dependency>

    2.定义一个切面类

    package com.iflytek.edu.hnezzhxy.common.config; import com.iflytek.edu.hnezzhxy.model.ZsbmLog; import com.iflytek.edu.hnezzhxy.model.ZsbmUser; import com.iflytek.edu.hnezzhxy.service.BaseService; import com.iflytek.edu.hnezzhxy.util.StringUtils; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.ObjectUtils; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import javax.servlet.http.HttpServletRequest; import java.sql.Timestamp; /** * @version 1.0 * @description aop * @create 2020/06/28 15:36 */ @Aspect //告诉框架这是一个切面类 @Component public class WebLogAcpect { private Logger logger = LoggerFactory.getLogger(WebLogAcpect.class); /** 公共业务类注入 **/ @Autowired private BaseService baseService; /** * 定义切入点,切入点为com.iflytek.edu.hnezzhxy.service的EnterService类中的下的getMyEntrollZsbmStudentByID这个方法 */ @Pointcut("execution (public * com.iflytek.edu.hnezzhxy.service.EnterService.getMyEntrollZsbmStudentByID(..)))") public void WebLogAcpect(){} /** 前置通知 在切入点的目标方法执行完成之前触发 **/ @Before("WebLogAcpect()") public void before(JoinPoint joinPoint){ System.out.println("准备开始查询用户!"); } /** 后置通知 在切入点的目标方法执行完成之后触发**/ @After("WebLogAcpect()") public void after(JoinPoint joinPoint){ this.ifAfterThrowing(false); } /** 返回通知 在切入点的目标方法执行完成之后触发并且可以拿到返回值 **/ @AfterReturning("BrokerAspect()") public void doAfterReturningGame(){ System.out.println("返回通知:经纪人为球星表现疯狂鼓掌!"); } /** 后置异常通知 在目标方法执行之后出现异常时触发**/ @AfterThrowing("WebLogAcpect()") public void doAfterExeception(JoinPoint joinPoint){ this.ifAfterThrowing(true); } /** * 添加日志业务逻辑 * @param flag */ private void ifAfterThrowing(Boolean flag){ //获取RequestAttributes RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); //从获取RequestAttributes中获取HttpServletRequest的信息 HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST); Timestamp nowTime=new Timestamp(System.currentTimeMillis()); String ip = request.getHeader("x-forwarded-for"); Object obj = request.getSession().getAttribute(Constants.SESSION_USER_Attribute); StringBuilder str=new StringBuilder(); if(StringUtils.isBlank(ip)){ ip=request.getRemoteAddr(); } String uid=""; String userName=""; if(!ObjectUtils.isEmpty(obj)){ ZsbmUser user=(ZsbmUser)obj; uid=user.getUid(); userName=user.getUserName(); } ZsbmLog zsbmLog=new ZsbmLog(); if(flag){ str.append(userName).append("用户查询成绩失败!").append("ip地址为:") .append(ip).append(",查询时间为:").append(nowTime); zsbmLog.setOperateIp(ip).setCreateTime(nowTime).setOperateContent(userName+"用户查询成绩失败!") .setOperateType("select"); logger.error(str.toString()); }else{ str.append(userName).append("用户查询成绩成功!").append("ip地址为:") .append(ip).append(",查询时间为:").append(nowTime); zsbmLog.setOperateIp(ip).setCreateTime(nowTime).setOperateContent(userName+"用户查询成绩成功!") .setOperateType("select"); logger.info(str.toString()); } baseService.addSelectGradeLog(zsbmLog); } }

    3.模拟查询详情出错的时候添加查询ip,查询时间等记录日志 4.结论 网上很多人都说后置通知在切入点方法发生异常时候不会调用,经测试发现后置通知在目标方法出现异常时也会被调用

    Processed: 0.014, SQL: 9