springboot使用aop记录后台操作日志
1.Log注解
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//该注解可以放在controller类上,但是只有 modular 参数有效;
//该注解也可以放在controller类的方法上,如果只有方法上有Log注解,那么只会解析该注解上的信息,
//如果类和方法上都有Log注解,且方法上的 modular参数 不是默认值,那么以方法上的 modular 参数为准,否则以类上的 modular 参数为准;
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
/** 方法模块 */
String modular() default "";
/** 功能描述 */
String describe() default "";
}
2.日志信息封装DTO
import lombok.Data;
import lombok.ToString;
import java.time.LocalDateTime;
/**
* @ClassName LogMessage
* @Description: 日志数据封装
* @Author Jiajiajia
* @Version V1.0
**/
@Data
@ToString
public class LogMessage {
//操作人id
private Long operationUserId;
//操作人
private String operationUser;
//操作模块
private String modular;
//具体方法描述
private String describe;
//来源计算机ip地址
private String ip;
//操作状态
private byte state;
//请求类型
private String type;
//执行时间
private LocalDateTime createTime=LocalDateTime.now();
//其他信息
private String message;
public void setState(State state){
this.state=state.getState();
}
/**
* 操作状态的枚举类
*/
public enum State{
SUCCESS((byte)0),ERROR((byte)1);
private byte state;
State(byte state){
this.state=state;
}
public byte getState(){
return state;
}
}
}
3.注解解析
利用反射技术,获取注解所在类的类信息,方法信息,和注解信息
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* @ClassName AopTest
* @Author Jiajiajia
* @Version V1.0
**/
@Aspect
@Component
public class LogAopAdapter {
/**
* 如果同步操作那就在这里注入dao层,在doAfter或throwing方法中将message对象插入数据库;
* 如果异步操作,那就在doAfter或throwing方法中将message对象放入阻塞队列异步执行,或者使用mq,
* 或者使用springboot的异步事件等;
*/
// @Resource
// private LogAopDao logAopDao;
@Pointcut("@annotation(com.test.Log)")
public void log(){}
/**
* 前置通知
* @param joinPoint
* @throws Throwable
*/
@Before("log()")
public void doBefore(JoinPoint joinPoint) throws Throwable {
}
/**
* 后置通知
* @param joinPoint
* @throws Throwable
*/
@After("log()&&@annotation(logMessage)")
public void doAfter(JoinPoint joinPoint,Log logMessage)throws Throwable{
LogMessage message = getMessage(joinPoint,logMessage);
message.setState(LogMessage.State.SUCCESS);
System.out.println(message);
}
/**
* 异常通知
* @param joinPoint
* @param ex
* @throws Exception
*/
@AfterThrowing(value="log()&&@annotation(logMessage)", throwing="ex")
public void throwing(JoinPoint joinPoint,Log logMessage,Exception ex) throws Exception{
LogMessage message = getMessage(joinPoint,logMessage);
message.setMessage(ex.getMessage());
message.setState(LogMessage.State.ERROR);
System.out.println(message);
}
private LogMessage getMessage(JoinPoint joinPoint,Log mlog)throws Exception{
LogMessage message=new LogMessage();
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
message.setType(request.getMethod());
message.setIp(getUserRealIp(request));
Signature signature = joinPoint.getSignature();
Class c=signature.getDeclaringType();
if(!"".equals(mlog.describe())){
message.setDescribe(mlog.describe());
}
if(!"".equals(mlog.modular())){
message.setModular(mlog.modular());
}else{
Log clog=(Log)c.getAnnotation(Log.class);
if(clog!=null){
if(!"".equals(clog.modular())){
message.setModular(clog.modular());
}
}
}
return message;
}
/**
* 获取源主机ip地址
* @param request
* @return
* @throws UnknownHostException
*/
public static String getUserRealIp(HttpServletRequest request) throws UnknownHostException {
String ip;
if (request.getHeader("x-forwarded-for") == null) {
ip = request.getRemoteAddr();
} else {
ip = request.getHeader("x-forwarded-for");
}
if ("127.0.0.1".equals(ip)) {
ip = InetAddress.getLocalHost().getHostAddress();
}
return ip;
}
}
4.测试代码
测试代码
@Log(modular = "测试模块")
@RestController
public class TestController {
@GetMapping("test")
@Log(describe = "测试描述")
public String test(){
if(true){
//手动抛异常
throw new Exception("异常");
}
return "test";
}
}
评论区
请写下您的评论...
猜你喜欢
blog
spring aop实现操作日志记录
框架
3694
springaop实现操作日志记录此次的目的是实现对controller中的方法执行情况进行记录,记录的有方法执行时间,操作人,请求的路径,方法的入参,模块,功能等。并实现利用注解的方式实现对被操作
框架,springboot
88
springboot用自带的logback打印日志多环境打印生产环境输出到控制台和文件,一天一个文件,保留30天开发环境输出到控制台
二、logback-spring.xml配置文件详情?xmlversion="1.
blog
mysql日志分析
数据库
1266
MariaDB/MySQL中,主要有5种日志文件:1.错误日志(errorlog):记录mysql服务的启停时正确和错误的信息,还记录启动、停止、运行过程中的错误信息。2.查询日志(generallog):
blog
mysql日志分析【二进制日志】
数据库
1194
开启和设置二进制日志日志切换二进制日志相关参数二进制日志恢复数据库上一篇文章介绍了普通查询日志和慢查询日志等参考:mysql日志分析,本篇主要介绍二进制日志。一、什么是二进制日志 二进制日志主要记
git
940
码;完成编辑后,我们用gitadd将工作区文件添加到暂存区;然后利用gitcommit提交文件到我们自己的分支。操作命令:gitcheckoutfiles或者gitcheckout.:把文件从暂存区域复
框架
1282
}/pattern/layoutencoderpattern${PATTERN}/patterncharsetUTF-8/charset/encoder/appender!--下面配置一些第三方包的日志过滤级别,用
java项目
1394
springboot+mybatis配置多数据源并利用aop实现自动切换(demo)
spring/springmvc
1400
"spring在ioc容器中获取aop的受理对象",这句话是什么意思呢?有时候我们会在spring项目中对一下类进行代理,比如我们会用spring的aop和自定义注解对一些接口访问添加日志,再比如对
最新发表
归档
2018-11
12
2018-12
33
2019-01
28
2019-02
28
2019-03
32
2019-04
27
2019-05
33
2019-06
6
2019-07
12
2019-08
12
2019-09
21
2019-10
8
2019-11
15
2019-12
25
2020-01
9
2020-02
5
2020-03
16
2020-04
4
2020-06
1
2020-07
7
2020-08
13
2020-09
9
2020-10
5
2020-12
3
2021-01
1
2021-02
5
2021-03
7
2021-04
4
2021-05
4
2021-06
1
2021-07
7
2021-08
2
2021-09
8
2021-10
9
2021-11
16
2021-12
14
2022-01
7
2022-05
1
2022-08
3
2022-09
2
2022-10
2
2022-12
5
2023-01
3
2023-02
1
2023-03
4
2023-04
2
2023-06
3
2023-07
4
2023-08
1
2023-10
1
2024-02
1
2024-03
1
2024-04
1
标签
算法基础
linux
前端
c++
数据结构
框架
数据库
计算机基础
储备知识
java基础
ASM
其他
深入理解java虚拟机
nginx
git
消息中间件
搜索
maven
redis
docker
dubbo
vue
导入导出
软件使用
idea插件
协议
无聊的知识
jenkins
springboot
mqtt协议
keepalived
minio
mysql
ensp
网络基础
xxl-job
rabbitmq
haproxy
srs
音视频
webrtc
javascript
目录
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。