It turns out that recording system logs is so simple [Java] [SpringBoot] [Mybatis Plus] [AspcetJ]

TaugongCool breezeThrough the ages, who is there to dare to be called a man?
Insert picture description here


Preface

This article is a simple application of aspect-oriented programming. What is used in the following is the recording of the post-notification implementation log. When the method is executed, the relevant log information is recorded. Commonly used annotations in AspectJ:
@AspectJ: define an aspect
@Before: pre-notification
@AfterReturning: post-notification
@Around: surround notification
@AfterThrowing: exception notification
@After: final notification

Tip: The following is the content of this article, the following cases are for reference

1. What is the system log

The system log is to record the information of the hardware, software and system problems in the system, and it can also monitor the events that occur in the system. Users can use it to check the cause of the error, or to find the traces left by the attacker when it was attacked. System logs include system logs, application logs, and security logs.

2. Development technology

  1. idea 2019
  2. SpringBoot
  3. MybatisPlus
  4. Druid connection pool

Three, development steps

3.1 Introduce dependent coordinates

3.1.1 Import Lombok

<dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
   <version>1.18.16</version>
   <scope>provided</scope>
</dependency>

3.1.2 Database connection dependency

<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.48</version>
</dependency>

3.1.3 spring aop dependency

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-aop</artifactId>
   <version>5.2.12.RELEASE</version>
</dependency>

3.1.4 aspectJ dependency

<dependency>
	 <groupId>org.springframework</groupId>
	 <artifactId>spring-aspects</artifactId>
	 <version>5.2.12.RELEASE</version>
</dependency>

3.1.5 Druid connection pool (Alibaba)

<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>druid</artifactId>
  <version>1.2.4</version>
</dependency>

3.1.6 mybatis-plus dependency

<dependency>
	 <groupId>com.baomidou</groupId>
	 <artifactId>mybatis-plus-boot-starter</artifactId>
	 <version>3.4.1</version>
</dependency>

3.2 Placement application.yml

server:
  port: 8088
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    url: jdbc:mysql://localhost:3306/aop-test?useSSL=false&useUnicode=true&characterEncoding=UTF-8
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver

The code is as follows (example):

3. 3 write entity class

3.4.1 System user entity


/**
 * <p>用户实体</p>
 * @author XinLiu 
 */
@Data
@ToString
@TableName(value = "sysUser")
public class SysUser {
    
    
    /**
     * 主键
     */
    @TableId
    private String id;
    /**
     * 用户名
     */
    @TableField("name")
    private String name;
    /**
     * 密码
     */
    @TableField("password")
    private String password;
    /**
     * 创建时间
     */
    @TableField("createDate")
    private Date createDate;
}

Corresponding data sheet:

Insert picture description here

3.4.2 Log entities

/**
 * <p>日志实体</p>
 * @author XinLiu 
 */
@Data
@ToString
@TableName("log")
public class SysLog {
    
    
    /**
     * 主键
     */
    @TableId
    private String id;
    /**
     * 访问的类名
     */
    @TableField("className")
    private String className;
    /**
     * 执行的操作
     */
    @TableField("methodName")
    private String methodName;
    /**
     * 创建日志时间
     */
    @TableField("createDate")
    private Date createDate;

}

Corresponding data sheet:
Insert picture description here

3.4 Write log notes

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
    
    
    /**
     * 执行操作的名称
     * @return 操作名
     */
    
    String value() ;
}

3.5 Write notification class

Here is actuallyAspect-oriented programmingThe typical application of the log here is usedPost notification, That is, perform this post notification when the accessed method returns correctly. First we need to write aEntry point, Which is to declare which method or methods are to be executed. We previously defined an annotation:, @Logthis annotation has an attribute value, and its function is to save executionSpecify the name of the operation; Next we need to write a post notification, which isEnhanceThe method requires a parameter JoinPoint joinPoint, through which the @Logannotation can be obtained, and the value on the annotation can be obtained through reflection. This value is the operation name and we need to save it in the log table; after writing the notification, we can save what we need to save Log information, such as: 访问者用户名、请求参数、请求的URI、请求者IP地址、执行的操作wait.


/**<p>通知类</p>
 * @author XinLiu 
 */
@SuppressWarnings("all")
@Component
@Aspect
public class LogAdvice {
    
    
    @Autowired
    private LogMapper logMapper;

    /**
     * 配置切入点
     */
    @Pointcut("@annotation(com.qingfeng.aoptest.common.anno.Log)")
    private void serviceAspect() {
    
    
    }

    /**
     * 后置通知,用于记录日志
     *
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @AfterReturning("serviceAspect()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
    
    
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        Log log = method.getAnnotation(Log.class);
        
        SysLog sysLog = new SysLog();
        sysLog.setId((UUID.randomUUID().toString()).replaceAll("-", ""));
        sysLog.setClassName(joinPoint.getTarget().getClass().getName());
        sysLog.setMethodName(log.value());
        sysLog.setCreateDate(new Date());
        
        logMapper.insert(sysLog);
    }
}

3.6 Writing mapper

3.6.1 LogMapper

To explain briefly, a BaseMapper<SysLog>class is inherited here , and by inheriting the class, we can usemybatis plusThe method inside, which implements common operations, such asCRUD

public interface LogMapper extends BaseMapper<SysLog> {
    
    
}

3.6.2 UserMapper

/**
 * <p>系统用户数据层</p>
 * @author XinLiu
 */
public interface UserMapper extends BaseMapper<SysUser> {
    
    
}

3.6.3 Writing mybaits-plus configuration class

This is a configuration class. @ConfigurationThe function of the annotation is to pass this class to the ioc container for processing; @MapperScan("com.qingfeng.aoptest.mapper")the function is to scan all mapper interfaces under the package path, simplifying the addition of annotations to the mapper class every time:, @Mapperif this is configured Class, you don’t need to write @Mapperannotations.

@Configuration
@MapperScan("com.qingfeng.aoptest.mapper")
public class MybatisPlusConfig {
    
    
}

3.7 Writing the service layer

3.7.1 UserService interface

/**
 * @author XinLiu
 */
public interface UserService extends IService<SysUser> {
    
    
    /**
     * 用户注册
     * @param sysUser 用户实体
     * @return
     */
    public boolean reg(SysUser sysUser);

    /**
     * 查询所有的用户
     * @return
     */
    public List<SysUser> queryAllUser();
}

3.7.2 UserService implementation code

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper,SysUser>  implements UserService    {
    
    
    @Autowired
    private UserMapper userMapper;
    /**
     * 用户注册
     *
     * @param sysUser 用户实体
     * @return
     */
    @Override
    @Log("用户注册")
    public boolean reg(SysUser sysUser) {
    
    
        return userMapper.insert(sysUser)>0;
    }

    @Override
    @Log("查询所有的用户")
    public List<SysUser> queryAllUser() {
    
    
        return userMapper.selectList(new QueryWrapper<SysUser>());
    }
}

Fourth, code testing

4.1 Writing test classes

@SpringBootTest
@RunWith(SpringRunner.class)
class AopTestApplicationTests {
    
    
    @Autowired
    private UserService userService;
    @Test
    void contextLoads() {
    
    
    }
 }

4.2 Test adding users

@Test
public void testReg(){
    
    
        System.out.println(userService);
        SysUser sysUser = new SysUser();
        sysUser.setCreateDate(new Date());
        sysUser.setId((UUID.randomUUID().toString()).replaceAll("-",""));
        sysUser.setName("admin");
        sysUser.setPassword("123456");
        userService.reg(sysUser);
 }

operation result:

Insert picture description here
Insert picture description here

4.3 Test to view all users

@Test
    public void  testFindAll(){
    
    
        List<SysUser> sysUsers = userService.queryAllUser();
        sysUsers.forEach(sysUser -> System.out.println(sysUser));
    }

operation result:
Insert picture description here

to sum up

Tip: Here is a summary of the article:
For example, the above is what I will talk about today. This article only briefly introduces how to implement logging through annotations and the use of AspectJ. It is helpful for a beginner to get started. This article also has Many things have not been implemented because there is no front-end written, and there are no users who visit in all logs.

Guess you like

Origin blog.csdn.net/qq_43073558/article/details/111406911