前几天有个项目需求,需要记录每一次的操作记录,一开始从接口里面写进去,感觉太冗余,太多重复的代码了,就单独拿出来。通过注解方式 ,那个接口加上注解就会记录这个操作记录
需要aop,再pom中添加
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
首先创建一个注解,只需要一个记录操作内容的参数就行
package com.yuyi.tool;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*
* @author lcc
* @data :2019年7月16日 下午3:57:58
*/
@Target(value = ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface EtxRecord {
// 操作内容
String value();
}
然后在连接SQL语句
@Mapper
public interface RecordDAO {
/**
* 新增项目日志
*/
@Insert("insert record_table values (null,#{prjectId},#{deptId},#{empId},#{recordContent},#{recordTime}) ")
Integer addRecord(@Param("prjectId")Integer prjectId, @Param("deptId")Integer deptId, @Param("empId")Integer empId,
@Param("recordContent")String recordContent, @Param("recordTime")LocalDateTime recordTime);
}
在接口里面写到,aop会用到
@Service
public class RecordServiceImpl implements RecordService {
@Autowired
private RecordDAO recordDAO;
@Override
@Transactional
public Integer addRecord(Integer prjectId, Integer deptId, Integer empId, String recordContent) {
LocalDateTime dateTime = LocalDateTime.now();
Integer i = recordDAO.addRecord(prjectId, deptId, empId, recordContent, dateTime);
return i;
}
}
下面是写aop,因为需要方法执行完再看看需不需要记录日志,就用的后置通知。
package com.yuyi.tool;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.yuyi.full.handler.exception.ResultBO;
import com.yuyi.service.RecordService;
/**
*
* @author lcc
* @data :2019年7月16日 下午4:09:12
*/
@Aspect
@Component
public class EtxAopRecord {
@Autowired
private RecordService recordService;
// 采用后置通知,接口返回正确才通知
@Pointcut("execution(public * com.yuyi.controller.*.*(..))")
public void rlAop() {
}
/**
* 封装数据
*/
public HttpServletRequest getRequest() {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
return request;
}
/**
* 后置通知
*/
@AfterReturning(value = "rlAop()", returning = "keys")
public void doBefore(JoinPoint joinPoint,ResultBO<?> keys) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
EtxRecord etxRecord = signature.getMethod().getDeclaredAnnotation(EtxRecord.class);
if (etxRecord != null) {
String recordContents = etxRecord.value();
// 获取接口里面得值
HttpServletRequest request = getRequest();
/** 项目Id */
Integer prjectId = Integer.valueOf(request.getParameter("prjectId"));
/** 部门Id */
Integer deptId = Integer.valueOf(request.getParameter("deptId"));
/** 用户Id */
Integer empId = Integer.valueOf(request.getParameter("empId"));
/** 判断方法是否执行成功 */
if (keys.getCode() == 0 && prjectId != null && empId != null) {
recordService.addRecord(prjectId, deptId, empId, recordContents);
}
}
}
}
下面测试一下
@RestController
public class RecordController {
@RequestMapping("addRecord")
@EtxRecord("测试")
public ResultBO<?> addRecord(
@RequestParam("prjectId")String prjectId,
@RequestParam("deptId")Integer deptId,
@RequestParam("empId")Integer empId
){
return ResultTool.error(ExceptionNum.PARAMETER_ERROR);
}
}
测试通过,还有点不完善的,后期继续跟进