In the Spring framework, using AOP in conjunction with custom annotations makes it easy to monitor user actions. Start Spring Boot with a basic Web environment, and then introduce necessary dependencies:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <! GroupId > <artifactId> Spring-boot-starter-AOP </artifactId> </dependency> <! Oracle </groupId> <artifactId>ojdbc6</artifactId> <version>6.0</version> </dependency> <! -- Druid data source driver --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> The < version > 1.1.6 < / version > < / dependency >Copy the code

Custom annotations

Define a method-level @log annotation for methods that need to be monitored:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
    String value() default "";
}Copy the code

Create library tables and entities

SQL > create table sys_log; create table sys_log;

CREATE TABLE "SCOTT"."SYS_LOG" ( "ID" NUMBER(20) NOT NULL , "USERNAME" VARCHAR2(50 BYTE) NULL , "OPERATION" VARCHAR2(50 BYTE) NULL , "TIME" NUMBER(11) NULL , "METHOD" VARCHAR2(200 BYTE) NULL , "PARAMS" VARCHAR2(500 BYTE) NULL , "IP" VARCHAR2(64 BYTE) NULL , "CREATE_TIME" DATE NULL ); COMMENT ON COLUMN "SCOTT"."SYS_LOG"."USERNAME" IS 'USERNAME '; COMMENT ON COLUMN "SCOTT"."SYS_LOG"."OPERATION" IS 'user operated '; COMMENT ON COLUMN "SCOTT"."SYS_LOG"."TIME" IS 'response TIME '; COMMENT ON COLUMN "SCOTT"."SYS_LOG"."METHOD" IS 'request METHOD '; COMMENT ON COLUMN "SCOTT"."SYS_LOG"."PARAMS" IS 'id '; COMMENT ON COLUMN "SCOTT"."SYS_LOG"."IP" IS 'IP address '; COMMENT ON COLUMN "SCOTT"."SYS_LOG"."CREATE_TIME" IS 'CREATE_TIME '; CREATE SEQUENCE seq_sys_log START WITH 1 INCREMENT BY 1;Copy the code

Entities corresponding to library tables:

public class SysLog implements Serializable{ private static final long serialVersionUID = -6309732882044872298L; private Integer id; private String username; private String operation; private Integer time; private String method; private String params; private String ip; private Date createTime; / / get, set slightly}Copy the code

Method of saving logs

For convenience, use the Spring JdbcTemplate directly to manipulate the database. Define a SysLogDao interface that contains an abstract method for storing operation logs:

public interface SysLogDao {
    void saveSysLog(SysLog syslog);
}Copy the code

Its implementation method:

@Repository public class SysLogDaoImp implements SysLogDao { @Autowired private JdbcTemplate jdbcTemplate; @Override public void saveSysLog(SysLog syslog) { StringBuffer sql = new StringBuffer("insert into sys_log "); sql.append("(id,username,operation,time,method,params,ip,create_time) "); sql.append("values(seq_sys_log.nextval,:username,:operation,:time,:method,"); sql.append(":params,:ip,:createTime)"); NamedParameterJdbcTemplate npjt = new NamedParameterJdbcTemplate(this.jdbcTemplate.getDataSource()); npjt.update(sql.toString(), new BeanPropertySqlParameterSource(syslog)); }}Copy the code

Facets and pointcuts

Define a LogAspect class, using the @aspect annotation to make it an Aspect, pointcut for the method annotated with the @log annotation, using the @around circular notification:

@Aspect @Component public class LogAspect { @Autowired private SysLogDao sysLogDao; @Pointcut("@annotation(com.springboot.annotation.Log)") public void pointcut() { } @Around("pointcut()") public Object around(ProceedingJoinPoint point) { Object result = null; long beginTime = System.currentTimeMillis(); Proceed (); // proceed(); } catch (Throwable e) { e.printStackTrace(); } // Run time (ms) long time = system.currentTimemillis () -beginTime; SaveLog (point, time); return result; } private void saveLog(ProceedingJoinPoint joinPoint, long time) { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); SysLog sysLog = new SysLog(); Log logAnnotation = method.getAnnotation(Log.class); if (logAnnotation ! = null) {// Description on annotations syslog.setOperation (logannotation.value ()); } // Request method name String className = joinPoint.gettarGet ().getClass().getName(); String methodName = signature.getName(); sysLog.setMethod(className + "." + methodName + "()"); Object[] args = joinPoint.getargs (); / / request method parameter names LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer (); String[] paramNames = u.getParameterNames(method); if (args ! = null && paramNames ! = null) { String params = ""; for (int i = 0; i < args.length; i++) { params += " " + paramNames[i] + ": " + args[i]; } sysLog.setParams(params); } / / access request it request. = HttpContextUtils getHttpServletRequest (); // Set the IP address syslog.setip (iputils.getipaddr (request)); // Simulate a syslog.setusername ("mrbird"); sysLog.setTime((int) time); sysLog.setCreateTime(new Date()); // Save system log syslogdao.savesyslog (sysLog); }}Copy the code

test

TestController:

@restController public class TestController {@log (" execute method 1 ") @getMapping ("/one") public void methodOne(String name) {} @log (" execute method 2 ") @getMapping ("/two") public void two () throws InterruptedException {thread.sleep (2000); } @log (" methodThree ") @getMapping ("/three") public void three (String name, String age) {}}Copy the code

The final project catalog is as follows:

To start the project, visit:

  • http://localhost:8080/web/one?name=KangKang
  • http://localhost:8080/web/two
  • http://localhost:8080/web/three?name=Mike&age=25

Query database:

SQL> select * from sys_log order by id; ID USERNAME OPERATION TIME METHOD PARAMS IP CREATE_TIME ---------- ---------- ---------- ---------- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 11 mrbird execution method a 6 com.springboot.controller.Test name: KangKang 127.0.0.1 08 - December - 17 Controller. MethodOne () 12 mrbird execution method 2 2000 com. Springboot. Controller. The Test 127.0.0.1 08 - December - 17 Controller. MethodTwo 13 mrbird execute () method 3 0 com. Springboot. Controller. The Test name: Mike the age: 25 127.0.0.1 08-12月-17 Controller. MethodThree ()Copy the code

source code

This article is published by OpenWrite!