Spring AOP 实现日志记录

Posted 闲言_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring AOP 实现日志记录相关的知识,希望对你有一定的参考价值。

一.导入依赖

        <!--spring 的 context core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.0.RELEASE</version>
        </dependency>
        <!--Aop 支持-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.4</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.13</version>
        </dependency>
        <!--setter 构造方法插件-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</version>
        </dependency>
        <!--log4j 依赖-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

二.编写 log4j 配置文件

### 配置根 ###
log4j.rootLogger = debug,console ,fileAppender,dailyRollingFile,ROLLING_FILE,MAIL,DATABASE

### 设置输出sql的级别,其中logger后面的内容全部为jar包中所包含的包名 ###
log4j.logger.org.apache=debug
log4j.logger.java.sql.Connection=debug
log4j.logger.java.sql.Statement=debug
log4j.logger.java.sql.PreparedStatement=debug
log4j.logger.java.sql.ResultSet=debug

### 配置输出到控制台 ###
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern =  %dABSOLUTE %5p %c1:%L - %m%n

### 配置输出到文件 ###
log4j.appender.fileAppender = org.apache.log4j.FileAppender
log4j.appender.fileAppender.File = logs/log.log
log4j.appender.fileAppender.Append = true
log4j.appender.fileAppender.Threshold = DEBUG
log4j.appender.fileAppender.layout = org.apache.log4j.PatternLayout
log4j.appender.fileAppender.layout.ConversionPattern = %-dyyyy-MM-dd HH:mm:ss  [ %t:%r ] - [ %p ]  %m%n

### 配置输出到文件,并且每天都创建一个文件 ###
log4j.appender.dailyRollingFile = org.apache.log4j.DailyRollingFileAppender
log4j.appender.dailyRollingFile.File = logs/log.log
log4j.appender.dailyRollingFile.Append = true
log4j.appender.dailyRollingFile.Threshold = DEBUG
log4j.appender.dailyRollingFile.layout = org.apache.log4j.PatternLayout
log4j.appender.dailyRollingFile.layout.ConversionPattern = %-dyyyy-MM-dd HH:mm:ss  [ %t:%r ] - [ %p ]  %m%n

### 配置输出到文件,且大小到达指定尺寸的时候产生一个新的文件 ###
log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender 
log4j.appender.ROLLING_FILE.Threshold=ERROR 
log4j.appender.ROLLING_FILE.File=rolling.log 
log4j.appender.ROLLING_FILE.Append=true 
log4j.appender.ROLLING_FILE.MaxFileSize=10KB 
log4j.appender.ROLLING_FILE.MaxBackupIndex=1 
log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout 
log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout

三.编写代码

(一)定义包含增强方法的类

Joint Point 简单说明

  1. getTarget() 获取当前对象
  2. getSignature().getName() 获得当前方法名
  3. getArgs() 获得传递的参数(形参)
/**
 * @Classname ServiceLog
 * @Description 包含增强方法的JavaBean
 * @Date 2021/12/14 16:59
 * @Created by 闲言
 */
public class ServiceLog 
    //获取log日志对象
    private Logger logger = Logger.getLogger(ServiceLog.class);

    /**
     * 前置增强的方法
     * @param joinPoint
     */
    public void before(JoinPoint joinPoint)
        logger.info("前置方法执行,当前对象为:"+joinPoint.getTarget()+" 方法为:"+joinPoint.getSignature().getName()+" 参数为:"+ Arrays.toString(joinPoint.getArgs()));
    

    /**
     * 后置增强的方法
     * @param joinPoint
     */
    public void afterRound(JoinPoint joinPoint,Object result)
        logger.info("后置方法执行,当前对象为:"+joinPoint.getTarget()+" 方法为:"+joinPoint.getSignature().getName()+" 返回值为:"+result);
    

(二)定义要增强的方法

public class UserServiceImpl implements UserService 

    @Override
    public void add(User user) 
        System.out.println("添加的用户为:"+user);
    

四.编写xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       https://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop
       https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--注入service-->
    <bean id="userService" class="cn.bloghut.service.impl.UserServiceImpl"/>
    <!--注入user-->
    <bean id="user" class="cn.bloghut.pojo.User">
        <property name="id" value="1"/>
        <property name="name" value="闲言"/>
        <property name="pwd" value="123"/>
    </bean>
    <!--注入切面-->
    <bean id="logger" class="cn.bloghut.aop.ServiceLog"/>

    <!--配置aop-->
    <aop:config>
        <!--配置切入点 表达式-->
        <aop:pointcut id="pt" expression="execution( * cn.bloghut.service..*.*(..))"/>
        <!--配置-->
        <aop:aspect ref="logger">
            <!--before() 方法定义为前置增强,并引用切入点pt-->
            <aop:before method="before" pointcut-ref="pt"/>
            <!--afterRound() 方法定义为后置增强,并引用切入点pt,通过returning属性指定名为result的参数注入返回值-->
            <aop:after-returning method="afterRound" pointcut-ref="pt" returning="result"/>
        </aop:aspect>
    </aop:config>

</beans>

五.测试代码

    public static void main(String[] args) 
        //加载配置文件
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //从容器中service获取实例
        UserService userServiceImpl = ac.getBean("userService", UserService.class);
        //从容器中获取user实例
        User user = ac.getBean("user", User.class);
        //执行添加方法
        userServiceImpl.add(user);
    

六.查看结果

以上是关于Spring AOP 实现日志记录的主要内容,如果未能解决你的问题,请参考以下文章

Spring_AOP 记录系统关键操作日志用法

我使用Spring AOP实现了用户操作日志功能

从头认识Spring-3.1 简单的AOP日志实现-某方法之前的前后记录日志

Spring AOP 实现日志记录

Spring Aop基于注解的实现

从头认识Spring-3.5 简单的AOP日志实现(注解版)-某方法之前的前后记录日志