Spring和AOP编程——构建一个日志记录的切面

一、引言

1.实验目的

利用Spring技术实现一个校友信息的收集和展示页面。要求采用MVC框架,要求加入依赖注入和面向切面的编程。

构建一个日志记录的切面。要求:

a. 对于所有的Alumni表的查询操作,记录各个操作的时间、用户,读取内容,存入ReadLog表格中。

b. 对于所有的Alumni表的更新(更新和删除)操作,记录各个操作的时间、用户,修改的新值和旧值,存入UpdateLog表格中(删除的新值为null)。

2.环境配置

  • 操作系统:Windows 10 X64
  • 编程工具:Intellij IDEA 2019.2×64,Navicat for MySQL
  • 数据库:Mysql
  • 环境:Java jdk 1.8

二、实验具体过程

1.创建数据库

(1)创建用户表user_info

在这里插入图片描述

(2)创建记录查询操作的日志表readlog,其中content为用户读取内容

在这里插入图片描述

(3)创建记录更新(更新和删除)操作的日志表updatelog,其中operation为用户操作,1表示用户更新信息表记录,0表示用户删除信息表记录

在这里插入图片描述

2.项目后端代码编写

(1)后端代码结构如下

在这里插入图片描述

(2)AOP层代码

具体代码如下:SpringAopTest.java
import com.example.aoptest.Entity.UserEntity;
import com.example.aoptest.Service.UpdatelogService;
import com.example.aoptest.Service.ReadlogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class SpringAopTest {

    @Autowired
    private ReadlogService readlogService;

    @Autowired
    private UpdatelogService updatelogService;


    //查询信息切点
    @Pointcut(value = "execution(* com.example.aoptest.Controller.UserController.findByAll(*))")
    public void findAOP(){

    }

    //更新信息切点
    @Pointcut(value = "execution(* com.example.aoptest.Controller.UserController.updateByUsername(..)))")
    public void updateAOP(){

    }

    //删除信息切点
    @Pointcut(value = "execution(* com.example.aoptest.Controller.UserController.deleteByUsername(*)))")
    public void deleteAOP(){

    }


    //将查询信息操作日志写入数据库
    @Before("findAOP()")
    public void beforeread(JoinPoint joinPoint){
        UserEntity userEntity =(UserEntity)joinPoint.getArgs()[0];
        readlogService.insert(userEntity);
        System.out.println("Before: " + joinPoint);
    }

    //将更新信息操作日志写入数据库
    @Before("updateAOP()")
    public void beforeupdate(JoinPoint joinPoint){
        UserEntity userEntity =(UserEntity)joinPoint.getArgs()[0];
        String username=String.valueOf(joinPoint.getArgs()[1]);
        updatelogService.insertUpdate(userEntity,username);
        System.out.println("Before: " + joinPoint);
    }

    //将删除信息操作日志写入数据库
    @Before("deleteAOP()")
    public void beforedelete(JoinPoint joinPoint) {
        String username = String.valueOf(joinPoint.getArgs()[0]);
        updatelogService.insertDelete(username);
        System.out.println("Before: " + joinPoint);
    }
}

(3)Controller层代码

具体代码如下:UserController.java

在这里插入图片描述

(4)Entity层代码

具体代码如下:UserEntity.java

在这里插入图片描述

Readlog.java

在这里插入图片描述

Updatelog.java

在这里插入图片描述

(5)Mapper层代码

具体代码如下:UserMapper.java

在这里插入图片描述

ReadlogMapper.java

在这里插入图片描述

UpdatelogMapper.java

在这里插入图片描述

(6)Service层代码

具体代码如下:UserService.java

在这里插入图片描述

ReadlogService.java

在这里插入图片描述

UpdatelogService.java

在这里插入图片描述

3.运行结果

(1)记录用户jojo查询个人信息操作

user_info表中的用户jojo的信息如下:
在这里插入图片描述
在查询操作之前的readlog表中无数据记录:
在这里插入图片描述
执行查询信息的测试代码:
在这里插入图片描述
执行输出结果如下:
在这里插入图片描述

数据库readlog表中被写入数据,其中content是查询到的数据的内容:

在这里插入图片描述

(2)记录用户jojo的更新个人信息操作

user_info表中的用户jojo的更新之前的信息如下:
在这里插入图片描述
在更新操作之前的updatelog表中无数据记录:
在这里插入图片描述
执行更新信息的测试代码:
在这里插入图片描述
执行输出结果如下:
在这里插入图片描述
数据库updatelog表中被写入数据:
在这里插入图片描述
可以看到modify_old中是未修改的phone12345678901,modify_new是修改后的phone1234,operation为1表示为修改操作

下面是修改后的user_info表:
在这里插入图片描述

(3)记录用户jojo的删除个人信息操作

在删除操作之前updatelog表中只有1条更新操作的数据记录:
在这里插入图片描述
执行删除信息的测试代码:
在这里插入图片描述
执行输出结果如下:
在这里插入图片描述
数据库updatelog表中被写入一条删除数据的操作记录:
在这里插入图片描述
可以看到modify_old中是未更新(删除)之前的数据记录,modify_new是更新(修改)之后的数据(记录为null),operation为0表示为删除操作

再看user_info表中用户jojo已被删除:
在这里插入图片描述

三、总结

在本次实验中遇到了一些问题,现在总结一下:

(1)在连接数据库时遇到了错误[08001] Could not create connection to database server. Attempted reconnect 3 times. Giving up.之后查资料发现这是因为安装mysql的时候时区设置的默认是美国的时区,而我们中国大陆要比他们迟8小时,采用+8:00格式。使用的数据库是MySQL,在没有指定MySQL驱动版本的情况下它自动依赖的驱动是8.0.16很高的版本,这是由于数据库和系统时区差异所造成的,在jdbc连接的url后面加上serverTimezone=GMT即可解决问题。
在这里插入图片描述
(2)mybatis配置时出现错误rg.apache.ibatis.binding.BindingException: Invalid bound statement (not found)!这个错误导致无法将mapper层的代码映射到xml文件当中,就无法对数据库进行操作。解决方法是在application.properties配置文件中指定xml文件夹和实体的文件夹路径。
在这里插入图片描述
(3)Aop在设置切点的时候,如果拦截的controller层的方法有两个参数不能用*来匹配,要用…否则无法匹配
在这里插入图片描述
(4)本次实验还学会了使用MybatisCodeHelper pro工具来自动生成实体层、mapper层以及xml的代码,自动生成代码对于Spring框架来说减轻了不少负担,而且出错的概率也大大降低,但缺点是对于xml层的sql语句的具体写法可能就不够熟练了。
在这里插入图片描述

四、参考链接

[1] java切面做日志记录

[2] Spring AOP 基于注解实现日志记录+自定义注解

[3] Spring和AOP编程

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值