Spring:Aop记录日志

Spring:Aop记录日志

本博客默认读者已经了解Aop原理,有spring基础,不在此详细描述。

AOP简介

AOP(Aspect Oriented Programming),即面向切面编程。 (OOP:Object 面向对象编程)

有了AOP,你写代码时不需要把这个验证用户步骤写进去,即完全不考虑验证用户。只写取款和显示余额的业务代码。而在另一个地方,写好验证用户的代码。这个验证用户的代码就是切面代码,以后在执行取款和显示余额的时候,利用代理模式。将验证用户的功能在执行取款和显示余额前调用。

代码在Spring容器中执行的时候,通过配置告诉Spring你要把这段代码加到哪几个地方,Spring就会在执行正常业务流程的时候帮你把验证代码和取款代码织入到一起。

AOP真正目的是:你写代码的时候,只需考虑主流程,而不用考虑那些不重要的,但又必须要写的其它相同的代码,这些其它的相同代码所在的类就是切面类。

关键词解释

Aspect(切面):切面指的是切入点(规则)和通知(织入方法)的类=切入点+通知

Pointcut(切入点):切入点指的是类或方法名,满足某一个规则的类或方法都是切入点,通过切入点表达式来指定规则。

Advice(通知):切入点处所要执行的程序代码,即切面类中要执行的公共方法。通知的类型有:前置通知,后置通知,异常通知,最终通知,环绕通知。

在这里插入图片描述

以黑马项目二为例

步骤

  1. 编写SpringMVC.xml,开启Aop自动代理
  2. 编写日志切面类(@Aspect),在切面类中需要保存日志
  3. 测试Aop,自动记录日志

实现
Aop(面向切面编程)是spring框架的一个特点,在实现Aop功能的时候需要在springmvc.xml文件中开启aop的注解扫描。

1. 编写springmvc.xml,开启Aop自动代理

 <!--开启aop的注解扫描 自动扫描@Aspect、@pointCut、@Around这些注解-->
    <aop:aspectj-autoproxy/>

在这里插入图片描述

2. 编写日志切面类

注解说明:

  • 类上的注解

@Component
@Aspect
public class LogAspect {

在切面类的类名上加上@Component,表示将该类注册到spring容器中
在切面类的类名上加上@Aspect,通过此注解标识为切面类

  • 方法上的注解

@Around(“execution(* com.cheung.web.controller...(…)) &&! execution( com.cheung.web.controller.system.SysLogController.*(…))”)

@Around表示将该方法标记为环绕通知,其中参数为切入点表达式(切入点表达式是可以使用逻辑运算符)

  • 切入点表达式

切入点表达式由以下部分组成:
访问修饰符 返回类型 包名.类名.方法名(参数类型) 抛出异常类型

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)

其中必须要填的参数是:
返回类型、方法名、参数类型

在切入点表达式中可以使用逻辑运算符

execution(* com.cheung.web.controller...(…)) &&! execution( com.cheung.web.controller.system.SysLogController.*(…))

本案例使用逻辑运算符将记录日志的controller排除在切面外,每次执行记录日志的时候就不会将“记录日志”这一没意义的日志保存到数据库。

环绕通知的要求:

public Object saveLog(ProceedingJoinPoint pj){方法体}

  1. 方法的返回值类型一定是Object,这里的返回值代表了目标方法的返回值

  2. 方法一定要有形参ProceedingJoinPoint ,ProceedingJoinPoint 代表的是目标方法

切面实现类代码:

package com.cheung.web.utils;

import com.cheung.domain.system.SysLog;
import com.cheung.domain.system.User;
import com.cheung.service.system.SysLogService;
import org.apache.shiro.web.session.HttpServletSession;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.UUID;

@Component
@Aspect
public class LogAspect {

    @Autowired
    private SysLogService sysLogService;

    @Autowired
    private HttpServletRequest request;



    @Around("execution(* com.cheung.web.controller.*.*.*(..)) &&! execution(* com.cheung.web.controller.system.SysLogController.*(..))")
    public Object saveLog(ProceedingJoinPoint pj){
        try {
            Object result = pj.proceed(); //放行目标方法
            //执行完毕了方法,那么就应该记录日志
            SysLog sysLog = new SysLog();
            //设置id
            sysLog.setId(UUID.randomUUID().toString());
            //得到登陆者
            User loginUser = (User) request.getSession().getAttribute("loginUser");
            //设置操作人
            sysLog.setUserName(loginUser.getUserName());
            //设置ip
            sysLog.setIp(request.getRemoteAddr());
            //时间
            sysLog.setTime(new Date());
            //执行的目标方法名
            sysLog.setMethod(pj.getSignature().getName());
            //设置目标方法所属的类全名
            sysLog.setAction(pj.getTarget().getClass().getName());//pj.getTarget()获取执行目标方法的对象
            sysLog.setCompanyId(loginUser.getCompanyId());
            sysLog.setUserName(loginUser.getCompanyName());
            sysLogService.save(sysLog);
            return result;
        }catch (Throwable throwable){
            throwable.printStackTrace();
            throw new RuntimeException(throwable);
        }
    }

}

3.测试Aop记录日志效果

在这里插入图片描述
通过Aop技术实现了记录日志功能,当用户访问控制器方法时候日志表就会自动记录日志。

Memorial Day is 472 days
I miss you
xiaokeai

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring AOP是一个强大的框架,可以帮助我们实现各种切面,其中包括日志记录。下面是实现日志记录的步骤: 1. 添加Spring AOP依赖 在Maven或Gradle中添加Spring AOP依赖。 2. 创建日志切面 创建一个用于记录日志的切面。这个切面可以拦截所有需要记录日志的方法。在这个切面中,我们需要使用@Aspect注解来声明这是一个切面,并使用@Pointcut注解来定义哪些方法需要被拦截。 ```java @Aspect @Component public class LoggingAspect { @Pointcut("execution(* com.example.demo.service.*.*(..))") public void serviceMethods() {} @Around("serviceMethods()") public Object logServiceMethods(ProceedingJoinPoint joinPoint) throws Throwable { // 获取方法名,参数列表等信息 String methodName = joinPoint.getSignature().getName(); Object[] args = joinPoint.getArgs(); // 记录日志 System.out.println("Method " + methodName + " is called with args " + Arrays.toString(args)); // 执行方法 Object result = joinPoint.proceed(); // 记录返回值 System.out.println("Method " + methodName + " returns " + result); return result; } } ``` 在上面的代码中,我们使用了@Around注解来定义一个环绕通知,它会在拦截的方法执行前后执行。在方法执行前,我们记录了该方法的名称和参数列表,然后在方法执行后记录了该方法的返回值。 3. 配置AOPSpring的配置文件中配置AOP。首先,我们需要启用AOP: ```xml <aop:aspectj-autoproxy/> ``` 然后,我们需要将创建的日志切面添加到AOP中: ```xml <bean id="loggingAspect" class="com.example.demo.aspect.LoggingAspect"/> <aop:config> <aop:aspect ref="loggingAspect"> <aop:pointcut id="serviceMethods" expression="execution(* com.example.demo.service.*.*(..))"/> <aop:around method="logServiceMethods" pointcut-ref="serviceMethods"/> </aop:aspect> </aop:config> ``` 在上面的代码中,我们将创建的日志切面声明为一个bean,并将其添加到AOP中。我们还定义了一个切入点,并将其与日志切面的方法进行关联。 4. 测试 现在,我们可以测试我们的日志记录功能了。在我们的业务逻辑中,所有匹配切入点的方法都会被拦截,并记录它们的输入和输出。我们可以在控制台中看到这些日志信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值