背景
本项目主要是利用apo注解实现了一个简单日志操作记录功能,
主要是为了圆自己一个心愿吧,因为记得2017年老大让我做一个日志记录系统,当时没有做出来, 现在利用aop注解实现了一个简单的日志记录系统,这个用在微小型项目上还行,一般项目都用es来做日志存储了。
代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>aoplog</groupId>
<artifactId>aoplog</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.3.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.3.1.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.74</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-annotation</artifactId>
<version>3.4.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-core</artifactId>
<version>3.4.2</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
<!-- MYSQL驱动,不可缺少 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
<!-- Spring Boot JDBC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<!--将resources目录下的配置文件编译进classes文件 -->
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
</project>
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/user0?useUnicode=true&characterEncoding=utf8
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
mybatis:
mapper-locations: classpath*:mapper/*.xml
type-aliases-package: com.huilongguan.entity #对应实体类路径
package com.huilongguan.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 日志实体
* @Author wangbiao
* @Date 12/11/21 9:13 PM
* @Decripition:
**/
@TableName("log_info")
@ApiModel(value = "日志对象", description = "")
@Data
public class LogInfoEntity implements Serializable {
private static final long serialVersionUID = 1L;
@TableId("id")
@ApiModelProperty("id")
private Long id;
@TableField("url")
@ApiModelProperty("请求地址")
private String url;
@TableField("class_name")
@ApiModelProperty("请求类")
private String className;
@TableField("method")
@ApiModelProperty("请求方法")
private String method;
@TableField("params")
@ApiModelProperty("请求参数")
private String params;
@TableField("method_description")
@ApiModelProperty("方法描叙")
private String methodDescription;
@TableField("result")
@ApiModelProperty("请求结果")
private Boolean result;
@TableField("message")
@ApiModelProperty("请求返回描叙")
private String message;
@TableField("code")
@ApiModelProperty("请求返回code")
private Integer code;
@TableField("user_name")
@ApiModelProperty("执行请求的用户人名")
private String userName;
@TableField("create_time")
@ApiModelProperty("请求时间")
private Date createTime;
}
package com.huilongguan.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/**
* @Author wangbiao
* @Date 12/11/21 9:43 PM
* @Decripition:
**/
@Data
@ApiModel("用户信息对象")
@TableName("user0")
public class UserInfoEntity {
@TableId
@ApiModelProperty("id")
private Long id;
@TableField("name")
@ApiModelProperty("用户名")
private String name;
@TableField("phone")
@ApiModelProperty("电话号码")
private String phone;
@TableField("email")
@ApiModelProperty("邮箱")
private String email;
@TableField("password")
private String password;
@TableField("sex")
private Integer sex;
@TableField("create_time")
private Date createTime;
}
package com.huilongguan.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author wangbiao
* @Date 12/11/21 8:59 PM
* @Decripition:
**/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Result<T> {
private Integer code;
private Boolean isSuccess;
private String message;
private T data;
public static Result success(){
Result result = new Result(1000,true,null,null);
return result;
}
public static <T> Result<T> success(T t){
Result result = new Result(1000,true,null,t);
return result;
}
public static Result fail(){
Result result = new Result(5000,false,null,null);
return result;
}
public static Result fail(String message){
Result result = new Result(5000,false,message,null);
return result;
}
public static Result fail(Integer code){
Result result = new Result(5000,false,null,code);
return result;
}
public static Result fail(Integer code,String message){
Result result = new Result(5000,false,message,code);
return result;
}
}
package com.huilongguan.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.huilongguan.entity.LogInfoEntity;
import org.springframework.stereotype.Repository;
@Repository
public interface LogInfoMapper extends BaseMapper<LogInfoEntity> {
}
package com.huilongguan.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.huilongguan.entity.UserInfoEntity;
import org.springframework.stereotype.Repository;
/**
* @Author wangbiao
* @Date 12/11/21 10:03 PM
* @Decripition:
**/
@Repository
public interface UserInfoMapper extends BaseMapper<UserInfoEntity> {
}
package com.huilongguan.service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huilongguan.dao.UserInfoMapper;
import com.huilongguan.entity.UserInfoEntity;
import org.springframework.stereotype.Service;
/**
* @Author wangbiao
* @Date 12/11/21 10:18 PM
* @Decripition:
**/
@Service
public class UserInfoService extends ServiceImpl<UserInfoMapper, UserInfoEntity> {
}
package com.huilongguan.controller;
import com.huilongguan.aspect.LogAnnotation;
import com.huilongguan.entity.Result;
import com.huilongguan.entity.UserInfoEntity;
import com.huilongguan.service.UserInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @Author wangbiao
* @Date 12/11/21 10:25 PM
* @Decripition:
**/
@RestController
@RequestMapping("/user")
@Api(tags = "用户管理")
public class UserInfoController {
@Autowired
private UserInfoService userInfoService;
@ApiOperation("查询用户信息")
@LogAnnotation(operateDescripetion = "查询用户信息")
@PostMapping("/getUserInfoList")
public Result<List<UserInfoEntity>> getUserInfoList(){
int a = 1/0;
List<UserInfoEntity> userInfoEntityList = userInfoService.list();
return Result.success(userInfoEntityList);
}
@ApiOperation("新增用户")
@LogAnnotation(operateDescripetion = "新增用户")
@PostMapping("/addUserInfo")
public Result addUserInfo(@RequestBody UserInfoEntity userInfoEntity){
userInfoService.save(userInfoEntity);
return Result.success();
}
@ApiOperation("删除用户")
@LogAnnotation(operateDescripetion = "删除用户")
@PostMapping("/deleteById")
public Result deleteById(@RequestParam Long id){
userInfoService.removeById(id);
return Result.success();
}
}
package com.huilongguan.aspect;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义日志注解
* @Author wangbiao
* @Date 12/8/21 4:43 PM
* @Decripition:
**/
@Target(ElementType.METHOD) // 方法注解
@Retention(RetentionPolicy.RUNTIME) // 运行时可见
public @interface LogAnnotation {
String operateDescripetion();// 记录日志的操作描叙
}
package com.huilongguan.aspect;
import com.alibaba.fastjson.JSONArray;
import com.huilongguan.dao.LogInfoMapper;
import com.huilongguan.entity.LogInfoEntity;
import com.huilongguan.entity.Result;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
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.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Date;
/**
* 日志切面
* @Author wangbiao
* @Date 12/8/21 4:41 PM
* @Decripition:
**/
@Component
@Aspect
@Slf4j
public class LogAspect {
@Autowired
private LogInfoMapper logInfoMapper;
@Pointcut("@annotation(com.huilongguan.aspect.LogAnnotation)")
public void pointCut(){};
@Around(value = "pointCut()")
public Object methodAround(ProceedingJoinPoint pjp)throws Throwable{
LogInfoEntity logInfoEntity = new LogInfoEntity();
//获取方法签名
MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
//获取方法
Method method = methodSignature.getMethod();
String className = methodSignature.getClass().getName();
String methodName = method.getName();
LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);
String methodDescription = logAnnotation.operateDescripetion();//方法的描叙
String url = getUrl(method); //方法的url
// 获取参数值
Object[] args = pjp.getArgs();
String paramers = args!=null&&args.length>0? JSONArray.toJSONString(args):null;
//获取操作的用户
String userName = "张三";
//返回结果
Boolean resultBool = false;
String message = null;
Integer code = null;
logInfoEntity.setUrl(url);
logInfoEntity.setClassName(className);
logInfoEntity.setMethod(methodName);
logInfoEntity.setParams(paramers);
logInfoEntity.setUserName(userName);
logInfoEntity.setCreateTime(new Date());
logInfoEntity.setMethodDescription(methodDescription);
try{
Result result = (Result)pjp.proceed();
resultBool = result.getIsSuccess();
message = result.getMessage();
code = result.getCode();
logInfoEntity.setResult(resultBool);
logInfoEntity.setMessage(message);
logInfoEntity.setCode(code);
logInfoMapper.insert(logInfoEntity);
return result;
}catch (Exception e){
log.error("程序报错:"+e.getMessage(),e);
code = 5000;
message = e.getMessage();
resultBool = false;
logInfoEntity.setResult(resultBool);
logInfoEntity.setMessage(message);
logInfoEntity.setCode(code);
logInfoMapper.insert(logInfoEntity);
return Result.fail(e.getMessage());
}
}
public static String getUrl(Method method){
String url = null;
Annotation[] annotations = method.getAnnotations();
if(annotations!=null&&annotations.length>0){
for(Annotation annotation:annotations){
if(annotation instanceof PostMapping){
String[] values = ((PostMapping) annotation).value();
if(values!=null&&values.length>0){
url = values[0];
}
}else if(annotation instanceof GetMapping){
String[] values = ((GetMapping) annotation).value();
if(values!=null&&values.length>0){
url = values[0];
}
}else if(annotation instanceof DeleteMapping){
String[] values = ((DeleteMapping) annotation).value();
if(values!=null&&values.length>0){
url = values[0];
}
}
}
}
return url;
}
}
package com.huilongguan;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* 本项目主要是利用apo注解实现了一个简单日志操作记录功能,
* 主要是为了圆自己一个心愿吧,因为记得2017年老大让我做一个日志记录系统,当时没有做出来,
* 现在利用aop注解实现了一个简单的日志记录系统,这个用在微小型项目上还行,一般项目都用es来做日志存储了。
* @Author wangbiao
* @Date 12/8/21 4:33 PM
* @Decripition:
**/
@SpringBootApplication
@MapperScan("com.huilongguan.dao")
@EnableSwagger2
public class SpringBootApplocationStarter {
public static void main(String[] args) {
SpringApplication.run(SpringBootApplocationStarter.class,args);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.huilongguan.dao.LogInfoMapper">
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.huilongguan.dao.UserInfoMapper">
</mapper>
CREATE TABLE `log_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`url` varchar(200) COLLATE utf8mb4_bin DEFAULT NULL,
`class_name` varchar(200) COLLATE utf8mb4_bin DEFAULT NULL,
`method` varchar(50) COLLATE utf8mb4_bin DEFAULT NULL,
`params` varchar(500) COLLATE utf8mb4_bin DEFAULT NULL,
`result` tinyint(1) DEFAULT NULL,
`message` longtext COLLATE utf8mb4_bin,
`code` int(11) DEFAULT NULL,
`user_name` varchar(20) COLLATE utf8mb4_bin DEFAULT NULL,
`create_time` datetime DEFAULT NULL,
`method_description` varchar(200) COLLATE utf8mb4_bin DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1469858491801583618 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
CREATE TABLE `user0` (
`id` bigint(20) NOT NULL,
`name` varchar(30) DEFAULT NULL COMMENT '名称',
`sex` tinyint(2) DEFAULT NULL COMMENT '性别 0-男,1-女',
`phone` varchar(15) DEFAULT NULL COMMENT '电话',
`email` varchar(30) DEFAULT NULL COMMENT '邮箱',
`password` varchar(20) DEFAULT NULL COMMENT '密码',
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8