前言
涉及到的技术:SpringBoot、MySQL、Spring-Data-JPA
AOP指面向切面
思路
通过aop,将每次请求的信息,记录保存到数据库中去。
代码实现
数据库
我们先建立一张数据库表sys_log,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| DROP TABLE IF EXISTS `sys_log`; CREATE TABLE `sys_log` ( `id` varchar(64) NOT NULL, `class_name` varchar(64) DEFAULT NULL, `method_name` varchar(64) DEFAULT NULL, `params` varchar(255) DEFAULT NULL, `exec_time` longblob, `remark` varchar(64) DEFAULT NULL, `create_date` varchar(64) DEFAULT NULL, `url` varchar(255) DEFAULT NULL, `ip` varchar(64) DEFAULT NULL, `http_method` varchar(100) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
目录结构:
项目的目录结构,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| ├─src ├─main ├─java │ └─com │ └─seamoon │ ├─aspect │ ├─controller │ ├─domain │ ├─interfaceAnnotation │ ├─repository │ └─service │ └─Impl └─resources ├─static └─templates
|
主要代码
通过Maven引入一些jar,比如:数据库驱动,JPA,AOP,hutool工具包
pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.4.4</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.6</version> </dependency>
|
配置完jar,写写配置文件,这里小编采用了yml后缀文件的格式:
1 2 3 4 5 6 7 8 9 10 11
| spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql: username: root password: root
jpa: hibernate: ddl-auto: update show-sql: true
|
sysLog.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| package com.seamoon.aop.domain;
import jdk.internal.vm.annotation.Stable; import lombok.Data;
import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table;
@Entity @Data public class SysLog {
@Id private String id;
@Column(nullable = false) private String className;
@Column(nullable = false) private String methodName;
@Column(nullable = false) private String params;
@Column(nullable = false) private Long execTime;
private String remark;
@Column(nullable = false) private String createDate;
private String url;
@Column(nullable = false) private String ip;
@Column(nullable = false) private String httpMethod; }
|
SysLogRepository.java
1 2 3 4 5 6 7 8 9 10
| package com.seamoon.aop.repository;
import com.seamoon.aop.domain.SysLog; import org.springframework.data.jpa.repository.JpaRepository;
public interface SysLogRepository extends JpaRepository<SysLog,String> {
}
|
SysLogService.java
1 2 3 4 5 6 7 8 9
| package com.seamoon.aop.service;
import com.seamoon.aop.domain.SysLog;
public interface SysLogService {
boolean saveSysLog(SysLog sysLog); }
|
SysLogServiceImpl.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package com.seamoon.aop.service.Impl;
import com.seamoon.aop.domain.SysLog; import com.seamoon.aop.repository.SysLogRepository; import com.seamoon.aop.service.SysLogService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;
@Slf4j @Service public class SysLogServiceImpl implements SysLogService { @Autowired private SysLogRepository sysLogRepository;
@Override public boolean saveSysLog(SysLog sysLog) { sysLogRepository.save(sysLog);
log.info("成功"); return true; } }
|
SysLogAnnotation.java
1 2 3 4 5 6 7 8 9 10 11
| package com.seamoon.aop.interfaceAnnotation;
import java.lang.annotation.*;
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface SysLogAnnotation { String value() default ""; }
|
SysLogAspect.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
| package com.seamoon.aop.aspect;
import cn.hutool.core.util.IdUtil; import com.google.gson.Gson; import com.seamoon.aop.domain.SysLog; import com.seamoon.aop.interfaceAnnotation.SysLogAnnotation; import com.seamoon.aop.service.SysLogService; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest; import java.lang.reflect.Method; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List;
@Aspect @Component public class SysLogAspect { @Autowired private SysLogService sysLogService;
@Pointcut("@annotation(com.seamoon.aop.interfaceAnnotation.SysLogAnnotation)") public void logPointCut() {}
@Around("logPointCut()") public Object around(ProceedingJoinPoint point) throws Throwable { long beginTime = System.currentTimeMillis(); Object result = point.proceed(); long time = System.currentTimeMillis() - beginTime; try { saveLog(point, time); } catch (Exception e) { } return result; }
private void saveLog(ProceedingJoinPoint joinPoint, long time) { SysLog sysLog = new SysLog(); ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); String ip = request.getRemoteAddr(); String httpMethod = request.getMethod(); String url = request.getRequestURL().toString(); sysLog.setIp(ip); sysLog.setHttpMethod(httpMethod); sysLog.setUrl(url); sysLog.setId(IdUtil.randomUUID());
MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod();
sysLog.setExecTime(time); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); sysLog.setCreateDate(dateFormat.format(new Date())); SysLogAnnotation annotation = method.getAnnotation(SysLogAnnotation.class); if(annotation != null){ sysLog.setRemark(annotation.value()); } String className = joinPoint.getTarget().getClass().getName(); String methodName = signature.getName(); sysLog.setClassName(className); sysLog.setMethodName(methodName); Object[] args = joinPoint.getArgs(); try{ List<String> list = new ArrayList<String>(); for (Object o : args) { list.add(new Gson().toJson(o)); } sysLog.setParams(list.toString()); }catch (Exception e){ } sysLogService.saveSysLog(sysLog); }
}
|
TestController.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package com.seamoon.aop.controller;
import com.seamoon.aop.interfaceAnnotation.SysLogAnnotation; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*;
@RestController @RequestMapping("/test") public class TestController {
@SysLogAnnotation("切面测试") @GetMapping("/test") public String test(@RequestParam("name") String name) { System.out.println("sys-name:"+name); return name; }
@GetMapping("/v") public String index(){ return "sueccs"; }
}
|
通过访问http://127.0.0.1:8080/test/test?name=123,查询数据库,得出数据。
致谢
感谢您到来,如对您有帮助,请给小编一点温暖~~