AOP切面记录日志-实操
2024-01-07 17:41:13
前言
? ? ? ? 记录日志的就是把很多重要的数据给记录下来,写到数据库中;可以写一个方法,组装好之日信息的参数穿进去,但这样做不是很优雅,因为对于日志来说,不是业务逻辑代码的一部分,不应该影响到业务代码的,所以,使用切面正好解决了这个问题。
使用案例
1、自定义注解
import java.lang.annotation.*;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
//参数类
Class< ? extends ConvertParam> convert();
//操作类型
BusinessType businessType() default BusinessType.OTHER;
}
这个Log注解就是使用在需要记录日志的地方,注解里面的参数,是需要在注解使用时传进去的,有些给了默认值的的就可以不传,如果传了就会覆盖掉
2、参数统一
上面的注解里面有一个参数类:
Class< ? extends ConvertParam> convert();
?这个是自定义的一个接口,作用是将我们任何的参数转换成切面注解能够使用的参数,实现标准化。例如:SysLog类,有两个属性,这个就是接口的标准返回值
public class SysLog {
private Integer id;
private String serviceName;
}
标准接口:
public interface ConvertParam<Param> {
SysLog convert(Param param);
}
不管你传递的Param是什么类型,你在实现这个convert方法的时候,都必须想办法将Param转换为SysLog,因为SysLog这个对象是你后面写入逻辑的标准对象,就不需要你去做if-else的判断了,这个其实用到了策略模式,来处理多种实现方式。
3、定义切面、切点
@Aspect
@Component
public class LogAspect {
@Resource
HttpServletRequest httpServletRequest;
/**
* 定义切面
*/
@Pointcut("@annotation(com.cart.cartservice.Log.annotation.Log)")
public void section() {
}
/**
* 环绕切点
*
* @param
* @return result
*/
@Around("section()")
public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
//注解修饰的方法的返回结果
Object result = joinPoint.proceed();
//切面逻辑,收集日志什么的
handleLog(joinPoint, result);
//这个别忘记了
return result;
}
@SneakyThrows
private void handleLog(ProceedingJoinPoint joinPoint, Object result) {
//标准三部曲,拿取注解
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Log logAnnotation = method.getAnnotation(Log.class);
//获取方法参数
Object[] args = joinPoint.getArgs();
//获取注解里面的通用接口,这一步就是接口的参数转换为标准类型,方便后续使用
Class<? extends ConvertParam> convert = logAnnotation.convert();
ConvertParam convertParam = convert.newInstance();
SysLog sysLog = convertParam.convert(args[0]);
//拿到sysLog 标准对象之后,就可以定义标准的写入逻辑,不需要做任何的类型判断了
}
}
切面配置你自定义的注解,只要是出现你注解的地方就是切面,然后就是切点和处理逻辑。
?4、使用注解
@Log(convert = IntegerConvertParamImpl.class,businessType = BusinessType.QUERY)
@GetMapping("{id}")
public ResponseEntity<Cart> queryById(@PathVariable("id") Integer id) {
return ResponseEntity.ok(this.cartService.queryById(id));
}
IntegerConvertParamImpl就是将接口的参数转换为标准SysLog的实现类
import com.cart.cartservice.Log.convert.ConvertParam;
import com.cart.cartservice.Log.entity.SysLog;
import org.springframework.stereotype.Service;
@Service
public class IntegerConvertParamImpl implements ConvertParam<Integer> {
@Override
public SysLog convert(Integer integer) {
SysLog sysLog = new SysLog();
sysLog.setId(integer);
return sysLog;
}
}
文章来源:https://blog.csdn.net/qq_42251944/article/details/135428022
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!