1. AOP란?
AOP: 관점 지향 프로그래밍
AOP는 특정 클래스나 특정 메서드에 중점을 두지 않고 많은 수의 리소스에 중점을 둡니다. 클래스와 메소드.
2.AOP 응용 시나리오 및 공통 용어
권한 제어, 캐시 제어, 트랜잭션 제어, 분산 추적, 예외 처리 등
대상: 대상 클래스, 즉 필요한 클래스 프록시됩니다. 예: UserService
Joinpoint(연결 지점): 소위 연결 지점은 가로챌 수 있는 메서드를 나타냅니다. 예: 모든 메소드
PointCut Pointcut: 향상된 연결 지점입니다. 예: addUser()
조언 알림/개선, 개선 코드. 예: after, before
Weaving(위빙): 새로운 프록시 객체 프록시를 생성하기 위해 타겟 객체에 향상된 어드바이스를 적용하는 과정을 말합니다.
Aspect(aspect): 진입점 포인트컷입니다. 및 알림 조합
3. AOP의 특징
1) 모듈 간의 결합을 줄이고 비즈니스 코드의 집합성을 향상시킵니다. (높은 응집력 및 낮은 결합도)
2) 코드 재사용성 향상
3) 시스템 확장성 향상. (상위 버전은 하위 버전과 호환됩니다.)
4) 원래 기능에 영향을 주지 않고 새로운 기능을 추가할 수 있습니다.
1. 종속성을 도입합니다.
<!-- Spring AOP --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
2. 로그 엔터티 클래스
@Getter @Setter @ApiModel(value = "Systemlog对象", description = "") public class Systemlog implements Serializable { private static final long serialVersionUID = 1L; @ApiModelProperty("ID") @TableId(value = "id", type = IdType.AUTO) private Integer id; @ApiModelProperty("用户名") private String userName; @ApiModelProperty("用户ID") private Integer userId; @ApiModelProperty("操作描述") private String operate; @ApiModelProperty("模块") private String module; @ApiModelProperty("创建日志时间") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date createTime; @ApiModelProperty("操作结果") private String result; }
3. 주석 클래스 쓰기(사용자 정의 로그 주석 클래스)
/** * controller层切面日志注解 * @author hsq */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface SystemControllerLog { // 操作描述 String operate(); // 模块 String module(); }
4. 작업 로그의 측면 클래스 쓰기
** * @author hsq */ @Aspect @Component public class SystemLogAspect { private static final Logger logger = LoggerFactory.getLogger(SystemLogAspect.class); @Autowired private ISystemlogService iSystemlogService; @Autowired private UserService userService; /** * Controller层切点 */ @Pointcut("@annotation(com.hsq.demo.config.SystemControllerLog)") public void SystemControllerLog(){ } /** * 前置通知 用于拦截Controller层记录用户的操作的开始时间 * @param joinPoint 切点 * @throws InterruptedException */ @Before("SystemControllerLog()") public void doBefore(JoinPoint joinPoint) throws InterruptedException{ logger.info("进入日志切面前置通知!"); } @After("SystemControllerLog()") public void doAfter(JoinPoint joinPoint) { logger.info("进入日志切面后置通知!"); } /**value切入点位置 * returning 自定义的变量,标识目标方法的返回值,自定义变量名必须和通知方法的形参一样 * 特点:在目标方法之后执行的,能够获取到目标方法的返回值,可以根据这个返回值做不同的处理 */ @AfterReturning(value = "SystemControllerLog()", returning = "ret") public void doAfterReturning(Object ret) throws Throwable { } /*** * 异常通知 记录操作报错日志 * * @param joinPoint * * @param e * */ @AfterThrowing(pointcut = "SystemControllerLog()", throwing = "e") public void doAfterThrowing(JoinPoint joinPoint, Throwable e) { logger.info("进入日志切面异常通知!!"); logger.info("异常信息:" + e.getMessage()); } //使用这个方法先注释前面三个方法,留before方法就行 /** * 通知包裹了目标方法,在目标方法调用之前和之后执行自定义的行为 * ProceedingJoinPoint切入点可以获取切入点方法上的名字、参数、注解和对象 * @param joinPoint */ @Around("SystemControllerLog() && @annotation(systemControllerLog)") public Result doAfterReturning(ProceedingJoinPoint joinPoint, SystemControllerLog systemControllerLog) throws Throwable { logger.info("设置日志信息存储到表中!"); //joinPoint.proceed() 结果集 //参数数组 Object[] args = joinPoint.getArgs(); //请求参数数据 String requestJson = JSONUtil.toJsonStr(args); //方法名 String methodName = joinPoint.getSignature().getName(); //得到request HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); //得到token String token = request.getHeader("token"); String userId = JWT.decode(token).getAudience().get(0); User user = userService.getById(userId); logger.info("得到用户信息:"+user.toString()); //写入数据库操作日志 Systemlog systemlog = new Systemlog(); systemlog.setUserId(user.getUid()); systemlog.setUserName(user.getUname()); systemlog.setOperate(systemControllerLog.operate()); systemlog.setModule(systemControllerLog.module()); systemlog.setCreateTime(new Date()); //存入返回的结果集 joinPoint.proceed() Result proceed = (Result) joinPoint.proceed(); systemlog.setResult(JSONUtil.toJsonStr(joinPoint.proceed())); //保存 saveSystemLog(systemlog); return proceed; } }
5. 데이터베이스 레코드 사용
위 내용은 SpringBoot가 AOP를 사용하여 인터페이스 작업 로그를 기록하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!