提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
本文主要描述面向切面编程AOP的用例
利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率
代码如下(示例):
org.springframework.boot spring-boot-starter-aop 2.6.4
代码如下(示例):
- @Documented
- @Retention(RetentionPolicy.RUNTIME)
- @Target({ElementType.TYPE, ElementType.METHOD})
- public @interface OptLog {
-
- /**
- * 操作日志类型
- *
- * @return
- */
- OperationTypeEnum scenesType();
-
- /**
- * 请求处理状态
- *
- * @return
- */
- int status() default 0;
-
- /**
- * 写SpEL表达式 获取request请求内容
- *
- * @return
- */
- String request() default "";
-
- /**
- * request请求内容的类型
- *
- * @return
- */
- Class> requestType() default String.class;
-
- /**
- * 默认 系统管理员
- * 其他的取当前登录人
- *
- * @return
- */
- String operationUser() default "系统管理员";
-
-
- /**
- * 默认 系统管理员
- * 其他的取当前登录人
- *
- * @return
- */
- long operationUserId() default 0L;
- }
- @Slf4j
- @Aspect
- @Component
- public class OptLogAspect {
- /**
- * 用于SpEL表达式解析.
- */
- private final SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
-
- /**
- * 用于获取方法参数定义名字.
- */
- private final DefaultParameterNameDiscoverer nameDiscoverer = new DefaultParameterNameDiscoverer();
-
- @Autowired
- private InLogRepository inLogRepository;
-
- @Pointcut("@annotation(com.yssk.interfaces.biz.annotation.OptLog)")
- public void optLogAspect() {
- }
-
- @Around("optLogAspect()")
- public Object doAround(ProceedingJoinPoint joinPoint) {
- Object obj = null;
- try {
- MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
- //获取方法参数值
- Object[] args = joinPoint.getArgs();
- OptLog optLog = getTargetAnnotation(joinPoint);
-
- String request = optLog.request();
- Class> requestType = optLog.requestType();
-
- // 获取request请求内容
- Object requestKeyVal = getValBySpEl(request, methodSignature, args, requestType);
- if(Objects.nonNull(requestKeyVal)){
- Long id = handleOptRecordBefore(requestKeyVal);
- log.info("rizhi:{}", id);
- obj = joinPoint.proceed();
- handleOptRecordAfter(id, obj);
- }
- } catch (Throwable e) {
- log.warn("记录请求日志出现异常...", e);
- }
- return obj;
- }
-
- private Long handleOptRecordBefore(Object request){
- log.info("请求日志保存");
- String jsonStr = JSONObject.toJSONString(request);
-
- String requestUrl = "";
- if(ObjectUtils.isNotEmpty(request)){
- if(request instanceof RequestDTO){
- requestUrl = ((RequestDTO>) request).getRequestUrl();
- }
- }
- // 保存请求日志
- InLog inLog = new InLog();
- inLog.setRequest(jsonStr);
- inLog.setRequestUrl(requestUrl);
- inLog.setStatus(0);
-
- inLogRepository.save(inLog);
-
- return inLog.getId();
- }
-
- private void handleOptRecordAfter(Long id, Object response){
- log.info("请求日志修改");
- String jsonStr = JSONObject.toJSONString(response);
-
- int status = 0;
- if(ObjectUtils.isNotEmpty(response)){
- if(response instanceof ResponseDTO){
- if(((ResponseDTO>) response).getError_code() == 0){
- status = 1;
- }
- }
- }
- // 修改请求日志
- LambdaUpdateWrapper
updateWrapper = new LambdaUpdateWrapper<>(); - updateWrapper.set(InLog::getStatus, status);
- updateWrapper.eq(InLog::getId, id);
- updateWrapper.set(InLog::getResponse, jsonStr);
- inLogRepository.update(updateWrapper);
- }
-
- /**
- * 获取注解
- * @param point
- * @return
- */
- public static OptLog getTargetAnnotation(JoinPoint point) {
- try {
- OptLog annotation = null;
- if (point.getSignature() instanceof MethodSignature) {
- Method method = ((MethodSignature) point.getSignature()).getMethod();
- if (method != null) {
- annotation = method.getAnnotation(OptLog.class);
- }
- }
- return annotation;
- } catch (Exception e) {
- log.warn("获取 {}.{} 的 @OptLog 注解失败", point.getSignature().getDeclaringTypeName(), point.getSignature().getName(), e);
- return null;
- }
- }
-
- /**
- * 解析spEL表达式
- */
- private Object getValBySpEl(String spEl, MethodSignature methodSignature, Object[] args, Class> classType) {
- try {
- //获取方法形参名数组
- String[] paramNames = nameDiscoverer.getParameterNames(methodSignature.getMethod());
- if (paramNames != null && paramNames.length > 0) {
- Expression expression = spelExpressionParser.parseExpression(spEl);
- // spring的表达式上下文对象
- EvaluationContext context = new StandardEvaluationContext();
- // 给上下文赋值
- for (int i = 0; i < args.length; i++) {
- context.setVariable(paramNames[i], args[i]);
- context.setVariable("p" + i, args[i]);
- }
- return expression.getValue(context, classType);
- }
- } catch (Exception e) {
- log.warn("解析请求日志的el表达式出错", e);
- }
- return null;
- }
- }
以上就是今天要讲的内容,本文仅仅简单介绍了aop的使用法。