热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

关于java:SpringBoot中Aspect实现切面以记录日志为例

明天咱们来说说spring中的切面Aspect,这是Spring的一大劣势。面向切面编程往往让咱们的开发更加低耦合,也大大减少了代码量,同时呢让咱们更专一于业务模块的开发,把那些与业务无关的货色提取进来,便于前期的保护和迭代。

明天咱们来说说spring中的切面Aspect,这是Spring的一大劣势。面向切面编程往往让咱们的开发更加低耦合,也大大减少了代码量,同时呢让咱们更专一于业务模块的开发,把那些与业务无关的货色提取进来,便于前期的保护和迭代。

视频看的能源节点的视频,整顿了这篇博客作为笔记,当前温习时候看看,也分享给有须要的小伙伴。

视频资源:https://www.bilibili.com/vide…

相干概念

1. 切面(Aspect):

首先要了解‘切’字,须要把对象设想成一个立方体,传统的面向对象变成思维,类定义实现之后(封装)。每次实例化一个对象,对类定义中的成员变量赋值,就相当于对这个立方体进行了一个定义,定义实现之后,就等着被应用,等着被回收。

面向切面编程则是指,对于一个咱们曾经封装好的类,咱们能够在编译期间或在运行期间,对其进行切割,把立方体切开,在原有的办法外面增加(织入)一些新的代码,对原有的办法代码进行一次加强解决。而那些加强局部的代码,就被称之为切面,如上面代码实例中的通用日志解决代码,常见的还有事务处理、权限认证等等。

2. 切入点(PointCut):

要对哪些类中的哪些办法进行加强,进行切割,指的是被加强的办法。即要切哪些货色。

3. 连接点(JoinPoint):

晓得了要切哪些办法后,剩下的就是什么时候切,在原办法的哪一个执行阶段退出减少代码,这个就是连接点。如办法调用前,办法调用后,产生异样时等等。

4. 告诉(Advice):

告诉被织入办法,改如何被加强。定义切面的具体实现。那么这外面就波及到一个问题,空间(切哪里)和工夫(什么时候切,在何时退出减少代码),空间咱们曾经晓得了就是切入点中定义的办法,而什么时候切,则是连接点的概念。

5. 指标对象(Target Object):

被一个或多个切面所告诉的对象,即为指标对象。

6. AOP代理对象(AOP Proxy Object):

AOP代理是AOP框架所生成的对象,该对象是指标对象的代理对象。代理对象可能在指标对象的根底上,在相应的连接点上调用告诉。

7. 织入(Weaving):

将切面切入到指标办法之中,使指标办法失去加强的过程被称之为织入。

AOP 必须的依赖


    org.springframework.boot
    spring-boot-starter-aop

日志实体类

package com.space.aspect.bo;

import lombok.Data;

/**
 * 系统日志bo
 */
@Data
public class SysLogBO {

    private String className;

    private String methodName;

    private String params;

    private Long exeuTime;

    private String remark;

    private String createDate;
}

日志service

package com.space.aspect.service;

import com.space.aspect.bo.SysLogBO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class SysLogService {

    public boolean save(SysLogBO sysLogBO){
        // 这里就不做具体实现了
        log.info(sysLogBO.getParams());
        return true;
    }

}

定义日志注解

package com.space.aspect.anno;

import java.lang.annotation.*;

/**
 * 定义系统日志注解
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog {
    String value() default "";
}

申明切面,实现日志记录

以上4点咱们的筹备工作曾经实现。接下来就是重点了

package com.space.aspect.aspect;

import com.google.gson.Gson;
import com.space.aspect.anno.SysLog;
import com.space.aspect.bo.SysLogBO;
import com.space.aspect.service.SysLogService;
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 java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
 * 系统日志切面
 */
@Aspect  // 应用@Aspect注解申明一个切面
@Component
public class SysLogAspect {

    @Autowired
    private SysLogService sysLogService;

    /**
     * 这里咱们应用注解的模式
     * 当然,咱们也能够通过切点表达式间接指定须要拦挡的package,须要拦挡的class 以及 method
     * 切点表达式:   execution(...)
          *
     * execution(public * *(..)) 任意的公共办法
     * execution(* set*(..)) 以set结尾的所有的办法
     * execution(* com.LoggerApply.*(..))com.LoggerApply这个类里的所有的办法
     * execution(* com.annotation.*.*(..))com.annotation包下的所有的类的所有的办法
     * execution(* com.annotation..*.*(..))com.annotation包及子包下所有的类的所有的办法
     * execution(* com.annotation..*.*(String,?,Long)) com.annotation包及子包下所有的类的有三个参数,第一个参数为String类型,第二个参数为任意类型,第三个参数为Long类型的办法
     * execution(@annotation(com.lingyejun.annotation.Lingyejun))
     */
    @Pointcut("@annotation(com.space.aspect.anno.SysLog)")
    public void logPointCut() {}

    /**
     * 盘绕告诉 @Around  , 当然也能够应用 @Before (前置告诉)  @After (后置告诉)
     * @param point
     * @return
     * @throws Throwable
     */
    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long beginTime = System.currentTimeMillis();
        Object result = point.proceed();
        long time = System.currentTimeMillis() - beginTime;
        try {
            saveLog(point, time);
        } catch (Exception e) {
        }
        return result;
    }

    /**
     * 保留日志
     */
    private void saveLog(ProceedingJoinPoint joinPoint, long time) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        SysLogBO sysLogBO = new SysLogBO();
        sysLogBO.setExeuTime(time);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        sysLogBO.setCreateDate(dateFormat.format(new Date()));
        SysLog sysLog = method.getAnnotation(SysLog.class);
        if(sysLog != null){
            //注解上的形容
            sysLogBO.setRemark(sysLog.value());
        }
        //申请的 类名、办法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        sysLogBO.setClassName(className);
        sysLogBO.setMethodName(methodName);
        //申请的参数
        Object[] args = joinPoint.getArgs();
        try{
            List list = new ArrayList();
            for (Object o : args) {
                list.add(new Gson().toJson(o));
            }
            sysLogBO.setParams(list.toString());
        }catch (Exception e){ }
        sysLogService.save(sysLogBO);
    }
}

测试

package com.space.aspect.controller;

import com.space.aspect.anno.SysLog;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

    @SysLog("测试")
    @GetMapping("/test")
    public String test(@RequestParam("name") String name){
        return name;
    }
}

这样,咱们就胜利实现了应用Aspect实现切面记录日志。


推荐阅读
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 本文介绍了在多平台下进行条件编译的必要性,以及具体的实现方法。通过示例代码展示了如何使用条件编译来实现不同平台的功能。最后总结了只要接口相同,不同平台下的编译运行结果也会相同。 ... [详细]
  • 2018年人工智能大数据的爆发,学Java还是Python?
    本文介绍了2018年人工智能大数据的爆发以及学习Java和Python的相关知识。在人工智能和大数据时代,Java和Python这两门编程语言都很优秀且火爆。选择学习哪门语言要根据个人兴趣爱好来决定。Python是一门拥有简洁语法的高级编程语言,容易上手。其特色之一是强制使用空白符作为语句缩进,使得新手可以快速上手。目前,Python在人工智能领域有着广泛的应用。如果对Java、Python或大数据感兴趣,欢迎加入qq群458345782。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 也就是|小窗_卷积的特征提取与参数计算
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了卷积的特征提取与参数计算相关的知识,希望对你有一定的参考价值。Dense和Conv2D根本区别在于,Den ... [详细]
author-avatar
Cherish雪蕊诗_425
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有