springboot实现基于aop的切面日志
作者:yhmoling 发布时间:2022-09-09 11:53:11
标签:springboot,aop,切面日志
本文实例为大家分享了springboot实现基于aop的切面日志的具体代码,供大家参考,具体内容如下
通过aop的切面方式实现日志
通切面拦截所有指定包下的所有方法
@Aspect
@Component
@EnableAspectJAutoProxy
public class LogAspect1{
? ? Logger logger = LoggerFactory.getLogger(LogAspect.class);
? ??
/**
?* 拦截切点
?*/
? ? @Pointcut("execution(*xx.xx.controller.*.*(..))")
? ? private void logPointCut() {
? ? ? ? logger.info("进入注解拦截");
? ? }
? ? //前置通知,在方法之前通知
? ? @Before(value = "logPointCut()")
? ? public void before(JoinPoint jp) {
? ? ? ? logger.info("方法调用前:" + "类名:" + jp.getTarget().getClass().getName() + "方法名 :" + jp.getSignature().getName());
? ? }
? ? //后置通知
? ? @After(value = "logPointCut()")
? ? public void doAfter(JoinPoint jp) {
? ? ? ? logger.info("方法调用结束:" + "类名:" + jp.getTarget().getClass().getName() + "方法名 :" + jp.getSignature().getName());
? ? }
? ? //环绕通知
? ? @Around("logPointCut()")
? ? public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
? ? ? ? logger.info("方法开始调用》》》》》》");
? ? ? ? Object retVal = pjp.proceed();
? ? ? ? logger.info("方法调用结束》》》》》》");
? ? ? ? return retVal;
? ? }
? ? //返回通知
? ? @AfterReturning(pointcut = "logPointCut()")
? ? public void doAfterReturning(JoinPoint jp) {
? ? ? ? logger.info("写入日志");
? ? }
? ? //异常通知
? ? @AfterThrowing(pointcut = "logPointCut()", throwing = "ex")
? ? public void doAfterThrowing(JoinPoint jp, Throwable ex) {
? ? ? ? logger.info("方法异常,异常信息:" + ex.getMessage());
? ? }
}
拦截自定义注解
定义一个日志注解,在所有要需要记录的方法上加盖注解即可被后续的aop拦截处理
代码如下
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
? ? /**
? ? ?* 日志主题
? ? ?*/
? ? public String title() default "";
? ? /**
? ? ?* 操作具体业务
? ? ?*/
? ? public String business() default "";
? ? /**
? ? ?* 是否保留请求参数
? ? ?*/
? ? public boolean isSaveRequestData() default false;
? ? /**
? ? * 日志的类别,主要用于日志的分开记录和查询
? ? **/
LogType logType() default LogType.LOGIN;
}
拦截切面的实现
@Aspect
@Component
@EnableAspectJAutoProxy
public class LogAspect {
? ? Logger logger = LoggerFactory.getLogger(LogAspect.class);
? ? @Autowired
? ? private ServiceDemo serviceDemo;
? ? /**
? ? ?* 拦截切点
? ? ?*/
? ? @Pointcut("@annotation(moling.evolution.demo.aop.annotation.Log)")
? ? private void logPointCut() {
? ? ??
? ? }
? ? //前置通知,在方法之前通知
? ? @Before(value = "logPointCut()")
? ? public void before(JoinPoint jp) {
? ? ? ? logger.info("方法调用前:" + "类名:" + jp.getTarget().getClass().getName() + "方法名 :" + jp.getSignature().getName());
? ? }
? ? //后置通知
? ? @After(value = "logPointCut()")
? ? public void doAfter(JoinPoint jp) {
? ? ? ? logger.info("方法参数:{}", jp.getArgs());
? ? ? ? logger.info(" ?{} || {}", jp.getStaticPart().getId(), jp.getStaticPart().getSourceLocation());
? ? ? ? jp.getStaticPart().getId();
? ? ? ? logger.info("方法调用结束:" + "类名:" + jp.getTarget().getClass().getName() + "方法名 :" + jp.getSignature().getName());
? ? }
? ? //环绕通知
? ? @Around("logPointCut()")
? ? public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
? ? ? ? logger.info("方法开始调用》》》》》》");
? ? ? ? Object retVal = pjp.proceed();
? ? ? ? logger.info("方法调用结束》》》》》》");
? ? ? ? return retVal;
? ? }
? ? //返回通知
? ? @AfterReturning(pointcut = "logPointCut()", returning = "object")
? ? public void doAfterReturning(JoinPoint jp, Object object) {
? ? ? ? System.out.println("返回通知");
? ? ? ? Log log = null;
? ? ? ? try {
? ? ? ? ? ? log = getAnnotationLog(jp);
? ? ? ? } catch (Exception e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? ? ? System.out.println(object);
? ? ? ? System.out.println(log);
? ? ? ? if (log != null) {
? ? ? ? ? ? logger.info(log.title());
? ? ? ? ? ? logger.info(log.business());
? ? ? ? ? ? logger.info(log.user());
? ? ? ? ? ? logger.info(log.isSaveRequestData() + "");
? ? ? ? } else {
? ? ? ? ? ? logger.error("获取注解信息失败");
? ? ? ? }
? ? ? ? serviceDemo.demo();
? ? }
? ? //异常通知
? ? @AfterThrowing(pointcut = "logPointCut()", throwing = "ex")
? ? public void doAfterThrowing(JoinPoint jp, Throwable ex) {
? ? ? ? logger.info("方法异常,异常信息:" + ex.getMessage());
? ? ? ? serviceDemo.error();
? ? }
? ? /**
? ? ?* 是否存在注解,如果存在就获取
? ? ?*/
? ? private Log getAnnotationLog(JoinPoint joinPoint) throws Exception {
? ? ? ? Signature signature = joinPoint.getSignature();
? ? ? ? MethodSignature methodSignature = (MethodSignature) signature;
? ? ? ? Method method = methodSignature.getMethod();
? ? ? ? if (method != null) {
? ? ? ? ? ? return method.getAnnotation(Log.class);
? ? ? ? }
? ? ? ? return null;
? ? }
}
基于事件通知实现日志的记录
拦截切面的实现
@Aspect
@Component
@EnableAspectJAutoProxy
public class LogAspectContext {
? ? Logger logger = LoggerFactory.getLogger(LogAspectContext.class);
? ? @Autowired
? ? private ApplicationContext applicationContext;
? ? /**
? ? ?* 拦截切点
? ? ?*/
? ? @Pointcut("@annotation(moling.evolution.demo.aop.annotation.Log)")
? ? private void logPointCut() {
? ? ? ? logger.info("进入注解拦截");
? ? }
? ? //返回通知
? ? @AfterReturning(pointcut = "logPointCut()", returning = "object")
? ? public void doAfterReturning(JoinPoint jp, Object object) throws Exception {
? ? ? ? applicationContext.publishEvent(new LogSuccessEvent(jp, null));
? ? }
? ? //异常通知
? ? @AfterThrowing(pointcut = "logPointCut()", throwing = "ex")
? ? public void doAfterThrowing(JoinPoint jp, Throwable ex) {
? ? ? ? logger.info("方法异常,异常信息:" + ex.getMessage());
? ? ? ? applicationContext.publishEvent(new LogSuccessEvent(jp, ex));
? ? }
? ? /**
? ? ?* 是否存在注解,如果存在就获取
? ? ?*/
? ? private Log getAnnotationLog(JoinPoint joinPoint) throws Exception {
? ? ? ? Signature signature = joinPoint.getSignature();
? ? ? ? MethodSignature methodSignature = (MethodSignature) signature;
? ? ? ? Method method = methodSignature.getMethod();
? ? ? ? if (method != null) {
? ? ? ? ? ? return method.getAnnotation(Log.class);
? ? ? ? }
? ? ? ? return null;
? ? }
}
@Slf4j
@Service
public class ApplicationListener implements org.springframework.context.ApplicationListener<LogSuccessEvent> {
? ? @Autowired
? ? private ServiceDemo demo;
? ? @Override
? ? public void onApplicationEvent(LogSuccessEvent event) {
? ? ? ? JoinPoint joinPoint = event.getJp();
? ? ? ? Throwable ex = event.getThrowable();
? ? ? ? if (ex == null) {
? ? ? ? ? ? demo.demo();
? ? ? ? } else {
? ? ? ? ? ? demo.error();
? ? ? ? }
? ? }
}
@Slf4j
public class LogSuccessEvent extends ApplicationEvent {
? ? /**
? ? ?* Create a new ApplicationEvent.
? ? ?*
? ? ?* @param source the component that published the event (never {@code null})
? ? ?*/
? ? private JoinPoint jp;
? ? private Throwable throwable;
? ? public LogSuccessEvent(Object source, Throwable throwable) {
? ? ? ? super(source);
? ? ? ? this.throwable = throwable;
? ? ? ? this.jp = (JoinPoint) source;
// ? ? ? ?Log logger = (Log) source;
// ? ? ? ?log.info(logger.title());
// ? ? ? ?log.info(logger.business());
// ? ? ? ?log.info(logger.user());
// ? ? ? log.info(logger.isSaveRequestData() + "");
? ? }
? ? public JoinPoint getJp() {
? ? ? ? return jp;
? ? }
? ? public Throwable getThrowable() {
? ? ? ? return throwable;
? ? }
}
来源:https://blog.csdn.net/weixin_43864445/article/details/105409686


猜你喜欢
- 满满的都是坑,因为服务器偷懒让客服端写统一下单,服务器只给了通知的url。微信的支付demo并没有统一下单的代码。读此文前先阅读: http
- ActivityThread功能它管理应用进程的主线程的执行(相当于普通Java程序的main入口函数),并根据AMS的要求(通过IAppl
- 一般在web应用中,对客户端提交上来的图片肯定需要进行压缩的。尤其是比较大的图片,如果不经过压缩会导致页面变的很大,打开速度比较慢,当然了如
- 读取resources下文件的方法网上有问答如下:问:new FileInputStream("src/main/resource
- 1.初始化顺序当Java创建一个对象时,系统先为该对象的所有实例属性分配内存(前提是该类已经被加载过了),接着程序开始对这些实例属性执行初始
- 1.对象序列化的介绍(1).NET支持对象序列化的几种方式二进制序列化:对象序列化之后是二进制形式的,通过BinaryFormatter类来
- 因公司业务需要,需要将原有的ERP系统加上支持繁体语言,但不能改变原有的编码方式,即:普通程序员感受不到编码有什么不同。经过我与几个同事的多
- 前言代码生成器,也叫逆向工程,是根据数据库里的表结构,自动生成对应的实体类、映射文件和接口。看到很多小伙伴在为数据库生成实体类发愁,现分享给
- 一、ServerSocket1.为了方便调试,先创建一个界面用于显示客户端连接信息基于javafx包写的一个简单界面! javafx.sce
- 本文实例讲述了Android基于TextView实现的跑马灯效果。分享给大家供大家参考,具体如下:package sweet.venst.a
- Java中PriorityQueue通过二叉小顶堆实现,可以用一棵完全二叉树表示。本文从Queue接口函数出发,结合生动的图解,深入浅出地分
- Web UI项目中, 很多 Spring controller 视图函数直接返回 html 页面, 还有一些视图函数是要重定向或转发到其他的
- Android上使调用OpenCV 2.4.10 实现二维码区域定位(Z-xing 码),该文章主要用于笔者自己学习中的总结,暂贴出代码部分
- 前言最近对 base-spring-boot 项目进行了升级。在将其用于应用开发中时遇到java.lang.ArrayStoreE
- Java 8中引入了CompletableFuture类,它是一种方便的异步编程工具,可以处理各种异步操作,如网络请求、文件IO和数据库操作
- 本文实例为大家分享了android实现文件读写的具体代码,供大家参考,具体内容如下读取/*** 文件读取* @param is 文件的输入流
- 1,从System.String[]转到List<System.String>System.String[] str={&quo
- Spring P标签的使用Spring的p标签是基于XML Schema的配置方式,目的是为了简化配置方式。由于Spring的p标签是spr
- 前言大家应该都遇到过,在工作和生活中经常要填写一些个人资料,这时候往往需要放证件照上去,但是有时候人家要求是红底或白底,但是偏偏不巧的是你以
- 本文实例分析了Android中GridView和ArrayAdapter用法。分享给大家供大家参考,具体如下:GridView是一个表格化的