AOP 实现日志记录的功能

本文介绍如何利用AOP技术在Spring Boot应用中实现数据库操作的日志记录功能,包括更新、插入和删除等操作,并详细说明了实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

要求:
在controller层对update , insert , delete类型的请求对应的方法 进行拦截, 然后获取方法的请求参数,
根据不同的请求类型, 想日志表中计入不同的内容. 这样就可以实现每次改动数据库中表时,就会记录日志.
一般日志表会会记录如下内容:
修改人id
表名称
修改数据行id
修改时间
请求端ip地址
修改内容
实现方式:
我们以update操作计入日志为例
在controller层的update类型的方法上加一个注解(可以是自定义注解, 也可以用springboot的注解)
单独定义一个切面类OperLogAspect , 将加在方法上的注解定义为一个切点.
对这个切点加一个前置通知, 前置通知里 执行计入日志信息的操作.

具体实现如下:
首先看controller层

public class CConsController extends BasicController<CCons,ICConsService>{
@PreAuthorize("hasAuthority('billing:cons:insert')")
	@PostMapping(value = "/insert")
	public ResponseResult<Object> insert(@RequestBody(required = false) Map<String, Object> paraMap) {...}
}

在insert方法前, 加了一个preAuthorize注解, 注解的value是billing:cons:insert

然后定义一个切面类

@Aspect
@Component
@Slf4j
public class OperLogAspect {
    @Pointcut("@annotation(org.springframework.security.access.prepost.PreAuthorize)")
    public void operLogPointCut(){

    }


  @Before(value = "operLogPointCut()")
    public void saveOperLog(JoinPoint joinPoint){
    // 从切面织入点处通过反射机制获取织入点处的方法
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            // 获取切入点所在的方法
            Method method = signature.getMethod();
            // 获取操作
            PreAuthorize preAuthorize = method.getAnnotation(PreAuthorize.class);
            String pre = preAuthorize.value();
            //如果pre中包含update的字符串的话, 记日志时将修改前数据和修改后数据都记录日志
            //如果pre中包含insert/delete的话, 记日志时只用将被改的数据计入日志即可
            Class<IBasicService> basicService = (Class<IBasicService>) ((ParameterizedType) joinPoint.getTarget().getClass().getGenericSuperclass()).getActualTypeArguments()[1];
                IBasicService service = (IBasicService) SpringUtil.getBean(basicService);
                Class<BasicEntity> entityClass = (Class<BasicEntity>) ((ParameterizedType) joinPoint.getTarget().getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        //表名称
        String tablename = entityClass.newInstance().getTableName();
		//从线程池获取用户信息
		//request中获取ip地址
		//创建日志模板类, 填入日志的数据
		//调用日志service的insert方法插入日志数据
	}
}

这里解释一些方法:
getTarget() 获取被调方法的代理类
getClass() 获取类类型
getGenericSuperclass() 获取类的带泛型的父类
joinPoint.getTarget().getClass().getGenericSuperclass(): 获取被调方法的代理类的类类型后获取该类的带泛型的父类
getActualTypeArguments()[0] : 获取第一个泛型
留意controller层, 会发现他的父类传了两个泛型 , 第一个是model , 第二个是service

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值