我来为你详细讲解如何使用AOP技术实现操作日志管理。
基于SpringBoot使用AOP技术实现操作日志管理
什么是AOP
AOP(Aspect Oriented Programming)面向切面编程,是一种编程技术,主要用于解决代码耦合、重复代码等问题。AOP通过把代码横向分离成切面,从而避免了代码的重复。
在Java语言中,AOP技术主要通过代理模式和动态字节码生成机制实现,Spring框架中也使用AOP技术。
SpringBoot中使用AOP技术实现操作日志管理
在SpringBoot中,可以通过AOP技术实现操作日志管理。具体实现步骤如下:
- 定义日志注解
定义一个标记日志类型的注解,例如@ManageLog
注解:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ManageLog {
String value() default "";
}
- 定义日志实体类
定义一个操作日志的实体类,例如Log
实体类:
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class Log {
private String id;
private String username;
private String auth;
private String operation;
private String description;
private String method;
private String params;
private String ip;
private Date insertTime;
}
- 定义切面
定义一个切面,通过@Around
注解拦截方法,并在方法执行前后进行日志记录。切面代码如下:
@Aspect
@Component
@Slf4j
public class LogAspect {
@Autowired
private LogService logService;
@Pointcut("@annotation(cn.edu.cuit.aopdemo.anno.ManageLog)")
public void pointCut() {}
@Around("pointCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
Object result = null;
try {
result = joinPoint.proceed();
} catch (Exception e) {
throw e;
} finally {
saveLog(joinPoint, result);
}
return result;
}
private void saveLog(ProceedingJoinPoint joinPoint, Object result) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
ManageLog manageLog = method.getAnnotation(ManageLog.class);
Log log = new Log();
log.setId(UUID.randomUUID().toString());
log.setAuth(SecurityContextHolder.getContext().getAuthentication().getAuthorities().toString());
log.setOperation(manageLog.value());
log.setMethod(signature.getDeclaringTypeName() + "." + signature.getName());
log.setParams(JSONArray.toJSONString(joinPoint.getArgs()));
log.setResult(JSONArray.toJSONString(result));
log.setIp(getIp());
log.setUsername(SecurityContextHolder.getContext().getAuthentication().getName());
log.setInsertTime(new Date());
logService.save(log);
}
private String getIp() {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
if (request == null) {
return "";
}
String ip = request.getHeader("x-forwarded-for");
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
}
- 在需要记录日志的方法上添加注解
在需要记录日志的方法上添加@ManageLog
标记,例如:
@ManageLog("登录系统")
public User login(String username, String password) {
// ...
}
- 记录日志到数据库
定义一个LogService
服务,用于把日志数据存储到数据库中,代码如下:
@Service
public class LogService {
private final LogMapper logMapper;
public LogService(LogMapper logMapper) {
this.logMapper = logMapper;
}
public void save(Log log) {
logMapper.insert(log);
}
}
示例
下面提供两个使用AOP技术实现操作日志管理的示例。
示例一:记录登录日志
定义一个UserController
控制器,代码如下:
@RestController
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@ManageLog("用户登录")
@PostMapping("/login")
public User login(String username, String password) {
return userService.login(username, password);
}
}
上述代码中,@ManageLog("用户登录")
注解用于标记该方法为登录操作,当该方法被调用时,AOP切面会拦截该方法,自动记录相关日志信息。
示例二:记录商品增加日志
定义一个ProductController
控制器,代码如下:
@RestController
public class ProductController {
private final ProductService productService;
public ProductController(ProductService productService) {
this.productService = productService;
}
@ManageLog("增加商品")
@PostMapping("/product")
public void add(Product product) {
productService.add(product);
}
}
上述代码中,@ManageLog("增加商品")
注解用于标记该方法为增加商品操作,当该方法被调用时,AOP切面会拦截该方法,自动记录相关日志信息。
至此,基于SpringBoot使用AOP技术实现操作日志管理的完整攻略已经介绍完毕。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解基于SpringBoot使用AOP技术实现操作日志管理 - Python技术站