Aop之输出日志保存在数据库中
1.需要的依赖
<dependencies>
<!-- AOP依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</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>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
2.切面类和注解
package com.py.pj.common.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author WL
* @version 创建时间:2020-9-17 19:10:00
* @Description 保存日志自定义注解
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SysLogRequired {
String value();
}
package com.py.pj.common.aspect;
import java.lang.reflect.Method;
import java.util.Date;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.py.pj.common.annotation.SysLogRequired;
import com.py.pj.sys.entity.SysLog;
import com.py.pj.sys.service.SysLogService;
/**
* @author WL
* @version 创建时间:2020-9-17 19:11:17
* @Description 切面类;实现日志的自动保存
*/
@Aspect
@Component
public class SysLogAspect {
private static final Logger log = LoggerFactory.getLogger(SysLogAspect.class);
@Autowired
private SysLogService sysLogService;
// 切入点;使用@annotation的方式,细粒度
@Pointcut("@annotation(com.py.pj.common.annotation.SysLogRequired)")
public void doSaveLog() {}
// 环绕通知;
@Around("doSaveLog()")
public Object around(ProceedingJoinPoint jp) throws Throwable{
long t1 = System.currentTimeMillis();
Object result = jp.proceed(); // 要执行的方法
long t2 = System.currentTimeMillis();
long t = t2-t1;
log.info("执行时间:{ }",t);
SaveLog(jp,t);
return result;
}
/**
* @param jp
* @param time
* getSignature(): 该方法主要获取被代理对象的属性名称集合
* getTarget():此处是获得了被代理类的对象Impl
* @throws JsonProcessingException
* @throws SecurityException
* @throws NoSuchMethodException
*/
private void SaveLog(ProceedingJoinPoint jp, long time) throws JsonProcessingException, NoSuchMethodException, SecurityException {
//List com.py.pj.sys.serviceImpl.SysDeptServiceImpl.findObjects()
MethodSignature ms = (MethodSignature) jp.getSignature(); //....方法全类名
System.out.println("ms="+ms);
Class<?> targetClass = jp.getTarget().getClass(); // 被代理的类的反射
String targetName = targetClass.getName(); //DaoImpl被代理的类对象的名字
System.out.println("targetName="+targetName);//com.py.pj.sys.serviceImpl.SysDeptServiceImpl
// 获取接口声明方法
String MethodName = ms.getMethod().getName();//findObjects
System.out.println("MethodName="+MethodName);
Class<?>[] parameterTypes = ms.getMethod().getParameterTypes();
// 暴力反射获取方法
Method targetMethod = targetClass.getDeclaredMethod(MethodName, parameterTypes);
//获取方法参数
Object[] paramObj = jp.getArgs();
System.out.println("paramObj="+paramObj);
String params = new ObjectMapper().writeValueAsString(paramObj);
String username = "weilong";
SysLog slog = new SysLog();
SysLogRequired operation = targetMethod.getDeclaredAnnotation(SysLogRequired.class);
if (targetMethod!=null) {
slog.setOperation(operation.value());
}
slog.setCreatedTime(new Date());
slog.setIp("1.1.1.1");
slog.setMethod(targetName+"."+MethodName);
slog.setParams(params);
slog.setUsername(username);
slog.setTime(time);
sysLogService.insertObjects(slog);
}
}
3.在需要添加日志的业务方法上添加注释
。。。。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。