引言:spring的面向切面一直没有着手真正自己做过,接下来小刘使用Aspect 实现注解日志。
1.aspect配置
<!-- Spring AOP 切面 模块 -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.2</version>
</dependency>
<!--
2.spring开启切面配置
<!--启动aop的注解-->
<aop:aspectj-autoproxy proxy-target-class="true" />
其他配置不再赘述;
3.自定义注解类:SysLog
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog {
String INSERT="增加";
String DELETE="删除";
String UPDATE="更改";
String SELECT="查询";
String OTHER="其他情况";
String value() default "";
String type() default "";
}
4.自定义日志实体类
private static final long serialVersionUID = 1L;
private Integer id;
private String type;//增删改查
private Integer userId;
private String username;
private String requestMsg;//请求信息
private String requestClass;//请求类
private String method;//请求方法
private String ip;//请求ip
private String desp;//日志描述
private String startTime;//请求时间
private String timeConsuming;//耗时
public SysLog(){
}
实体类其他方法以及mybatis保存不再赘述
5.日志切面类
@Aspect
@Component
public class SysLogAspect {
@Autowired
HttpServletRequest request;
@Autowired
SysLogDao sysLogDao;
/**
* 切入点
*/
@Pointcut("@annotation(com.annotation.SysLog)")
public void pointCut() {}
/**
* 环绕通知
*
* @param joinPoint
* @return
* @throws Throwable
*/
@Around("pointCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
long beginTime = System.currentTimeMillis();
Object result = joinPoint.proceed();
long time = System.currentTimeMillis() - beginTime;
com.pojo.SysLog log=new com.pojo.SysLog();
SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
log.setStartTime(dateformat.format(beginTime));
long l = time / 1000;
log.setTimeConsuming(String.valueOf(l)+"s");
saveSysLog(joinPoint, log);
return result;
}
/**
* 保存日志
*
* @param joinPoint
*/
private void saveSysLog(ProceedingJoinPoint joinPoint, com.pojo.SysLog logClass) throws UnknownHostException {
System.out.println("--------------------------切面日志");
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
SysLog log = method.getAnnotation(SysLog.class);
if (log.type()!=null){
logClass.setType(log.type());
}else {
logClass.setType("其他类型");
}
logClass.setDesp(log.value());
logClass.setRequestClass(joinPoint.getTarget().getClass().getName());
logClass.setMethod(signature.getName());
// // 请求的参数
// Object[] args = joinPoint.getArgs();
// if (args != null && args.length != 0 && args[0] != null) {
// System.out.println(args[0].toString());
// }
Map<String,Object> reqMap=new HashMap<>();
Map<String, String[]> parameterMap = request.getParameterMap();
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
reqMap.put(entry.getKey(),entry.getValue()[0]);//这里暂不考虑同名的请求参数
}
// String s = IPUtils.getIpAddress(request);
String addr = Utils.getIpAddr(request);
reqMap.put("ip",InetAddress.getByName(request.getServerName()).getHostAddress());//获取服务器IP地址
reqMap.put("req_ip",addr);
reqMap.put("url",request.getRequestURL());//url全路径
reqMap.put("uri",request.getRequestURI());//相对路径
logClass.setIp(InetAddress.getByName(request.getServerName()).getHostAddress());
ObjectMapper objJson = new ObjectMapper();
try {
String asString = objJson.writeValueAsString(reqMap);
logClass.setRequestMsg(asString);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
SysUser o = (SysUser) request.getSession().getAttribute("sysUser");
if (o!=null){
logClass.setUsername(o.getUsername());
logClass.setUserId(o.getId());
}
sysLogDao.insertSelective(logClass);
System.out.println("----------------------系统保存日志--------------------------------");
System.out.println(logClass);
}
用法如下:控制层配置注解
/**
* 初始化菜单
* @return
*/
@SysLog(value = "登录首页",type = SysLog.SELECT)
@RequestMapping(value = "/initMenu")
@ResponseBody
效果图如下:
无偿免费分享源码以及技术和面试文档,更多优秀精致的源码技术栈分享请关注微信公众号:gh_817962068649