package com.fig;import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.support.spring.PropertyPreFilters;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.t.request.RequestContextHolder;
import org.t.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import flect.Field;
import java.util.UUID;/*** @Description 统一切面日志输出* @Author zhengwd* @Date 2023/4/11 10:36**/
@Aspect
@Component
public class LogAspect {private final static Logger LOG = Logger(LogAspect.class);/*** 定义一个切点*/@Pointcut("execution(public * com.zwd.*.controller..*Controller.*(..))")public void controllerPointcut() {}@Before("controllerPointcut()")public void doBefore(JoinPoint joinPoint) throws Throwable {// 日志编号MDC.put("UUID", UUID.randomUUID() + "");// 开始打印请求日志ServletRequestAttributes attributes = (ServletRequestAttributes) RequestAttributes();HttpServletRequest request = Request();Signature signature = Signature();String name = Name();// 打印业务操作String nameCn = "";if (ains("list") || ains("query")) {nameCn = "查询";} else if (ains("save")) {nameCn = "保存";} else if (ains("delete")) {nameCn = "删除";} else {nameCn = "操作";}// 使用反射,获取业务名称Class clazz = DeclaringType();Field field;String businessName = "";try {field = Field("BUSINESS_NAME");if (!StringUtils.isEmpty(field)) {businessName = (String) (clazz);}} catch (NoSuchFieldException e) {("未获取到业务名称");} catch (SecurityException e) {("获取业务名称失败", e);}// 打印请求信息LOG.info("------------- 【{}】{}开始 -------------", businessName, nameCn);LOG.info("请求地址: {} {}", RequestURL().toString(), Method());LOG.info("类名方法: {}.{}", DeclaringTypeName(), name);LOG.info("远程地址: {}", RemoteAddr());// 打印请求参数Object[] args = Args();Object[] arguments = new Object[args.length];for (int i = 0; i < args.length; i++) {if (args[i] instanceof ServletRequest|| args[i] instanceof ServletResponse|| args[i] instanceof MultipartFile) {continue;}arguments[i] = args[i];}// 排除字段,敏感字段或太长的字段不显示String[] excludeProperties = {"shard"};PropertyPreFilters filters = new PropertyPreFilters();PropertyPreFilters.MySimplePropertyPreFilter excludefilter = filters.addFilter();excludefilter.addExcludes(excludeProperties);// 为空的会不打印,但是像图片等长字段也会打印LOG.info("请求参数: {}", JSONString(arguments, excludefilter));}@Around("controllerPointcut()")public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {long startTime = System.currentTimeMillis();Object result = proceedingJoinPoint.proceed();// 排除字段,敏感字段或太长的字段不显示String[] excludeProperties = {"password", "shard"};PropertyPreFilters filters = new PropertyPreFilters();PropertyPreFilters.MySimplePropertyPreFilter excludefilter = filters.addFilter();excludefilter.addExcludes(excludeProperties);LOG.info("返回结果: {}", JSONString(result, excludefilter));LOG.info("------------- 结束 耗时:{} ms -------------", System.currentTimeMillis() - startTime);return result;}}
注意:定义的切点目录需要修改成你项目对应的位置。否则会不生效。
package com.ller;import com.stant.ResponseDto;
import com.zwd.cases.domain.User;
slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;/*** @Description 文件上传* @Author zhengwd* @Date 2022/7/21 16:30**/
@Slf4j
@Controller
@RequestMapping("testup")
public class UploadController {public static final String BUSINESS_NAME = "文件上传";/*** 单个文件上传页面* @return*/@RequestMapping("/list")public ResponseDto list(User user) {ResponseDto responseDto = new ResponseDto();responseDto.setContent(user);return responseDto;}
}
此处的 BUSINESS_NAME 属性不能删了,LogAspect类中有使用!!!
package com.stant;public class ResponseDto<T> {/*** 业务上的成功或失败*/private boolean success = true;/*** 返回码*/private String code;/*** 返回信息*/private String message;/*** 返回泛型数据,自定义类型*/private T content;public String getCode() {return code;}public void setCode(String code) {de = code;}public boolean getSuccess() {return success;}public void setSuccess(boolean success) {this.success = success;}public String getMessage() {return message;}public void setMessage(String message) {ssage = message;}public T getContent() {return content;}public void setContent(T content) {t = content;}@Overridepublic String toString() {final StringBuffer sb = new StringBuffer("ResponseDto{");sb.append("success=").append(success);sb.append(", code='").append(code).append(''');sb.append(", message='").append(message).append(''');sb.append(", content=").append(content);sb.append('}');String();}
}
package com.zwd.cases.domain;import lombok.Data;/*** @Description 用户对象* @Author zhengwd* @Date 2023/4/11 14:55**/
@Data
public class User {private String name;private String age;
}
<dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>4.2.9.RELEASE</version></dependency>
fastjson依赖,看自己原先项目有没有了,有就不用加
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.79</version></dependency>
请求地址:localhost:8080/testup/list?name=zwd&age=1
查看控制台效果:
问:面向切面编程能做些什么?简单举例下
答:
// 面向切面编程(AOP)能够在不修改原有代码的情况下,通过切面(Aspect)来实现对代码的增强或者横切关注点的分离。常见的应用场景包括日志记录、性能统计、安全控制、事务处理等。下面是一个简单的例子,使用AOP实现对方法执行时间的统计:
// 定义一个切面类,使用@Aspect注解标注
@Aspect
public class TimeAspect {// 定义一个切点,匹配ample.demo包及其子包下的所有类的所有方法@Pointcut("execution(* ample.demo..*.*(..))")public void pointcut() {}// 定义一个前置通知,在目标方法执行前输出开始时间@Before("pointcut()")public void before(JoinPoint joinPoint) {System.out.println("开始执行:" + Signature() + ",参数:" + Args()));Args();}// 定义一个后置通知,在目标方法执行后输出结束时间和执行时间@AfterReturning(pointcut = "pointcut()", returning = "result")public void afterReturning(JoinPoint joinPoint, Object result) {System.out.println("执行完成:" + Signature() + ",返回值:" + result);}// 定义一个异常通知,在目标方法抛出异常时输出异常信息@AfterThrowing(pointcut = "pointcut()", throwing = "e")public void afterThrowing(JoinPoint joinPoint, Exception e) {System.out.println("执行出错:" + Signature() + ",异常信息:" + e.getMessage());}
}// 在Spring配置文件中开启AspectJ自动代理,并扫描TimeAspect所在的包
<aop:aspectj-autoproxy />
<context:component-scan base-package=ample.demo.aspect" />// 在需要统计执行时间的方法上添加@Aspect注解
@Service
public class UserServiceImpl implements UserService {@Override@TimeAspectpublic void addUser(User user) {// ...}
}
完结,撒花~~~
附相关其他日志:idea控制台显示日志规范化并存储控制台输出日志操作
本文发布于:2024-01-29 09:43:52,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170649263514400.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |