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.结论
网上很多人都说后置通知在切入点方法发生异常时候不会调用,经测试发现后置通知在目标方法出现异常时也会被调用