业务

业务可分为核心业务和拓展业务.

核心业务:
功能模块的实现业务
拓展业务:
日志,缓存,权限

拓展业务实现方式有两种:

  1. 直接在核心业务中实现
  2. 采用继承或组合方式实现

    AOP

    切面对象由切入点和通知方法构成:
  • 切入点:@Pointcut 执行拓展业务逻辑的入口
  • 通知方法:封装拓展业务逻辑

    AOP输出日志简单实现

  1. 创建标记注解, 自定义注解,用于此注解描述需要指定拓展业务的方法,简而言之就是标记

    1. @Target(ElementType.METHOD)
    2. @Retention(RetentionPolicy.RUNTIME)
    3. public @interface RequiredLog {
    4. String value() default "";
    5. }
  2. 使用@Pointcut定义切入点表达式,需要在表达式中描述定义切入点的方法

表达式定义方式:采用注解方式的表达式,常用方式如下:

  • 注解方式:@Pointcut("@annotation(com.jt.annotations.RequiredLog)"),参数为需要执行拓展业务的注解的全路径
  • Bean方式:@Pointcut("bean(resourceController)")参数为bean名称
  • within方式:@Pointcut("within(com.jt.controller.ResourceController)")
    1. @Slf4j
    2. @Component
    3. @Aspect
    4. public class LogAspect {
    5. /**
    6. * 使用@Pointcut定义切入点表达式,需要在表达式中描述定义切入点的方法<br/>
    7. * 表达式定义方式:采用注解方式的表达式或者Bean的方式<br/>
    8. * Bean方式:@Pointcut("bean(resourceController)")参数为bean名称
    9. * within方式:@Pointcut("within(com.jt.controller.ResourceController)")
    10. */
    11. @Pointcut("@annotation(com.jt.annotations.RequiredLog)")
    12. public void doLog() {
    13. }
  1. 在需要执行日志拓展业务的方法添加标记注解

    1. @Slf4j
    2. @RefreshScope
    3. @RestController
    4. @RequestMapping("/resource")
    5. public class ResourceController {
    6. @Value("${jt.resource.path:E:/images}")
    7. private String resourcePath;
    8. @Value("${jt.resource.host:http://localhost:8100/}")
    9. private String resourceHost;
    10. /**
    11. * 处理文件上传的请求<br/>
    12. * 其中@RequiredLog表示为切入点
    13. *
    14. * @param uploadFile 接受要上传的文件数据,参数名需与客户端参数名一致
    15. * @return 文件上传后在服务器中的实际存储路径, 使用基于http协议访问此文件夹
    16. */
    17. @RequiredLog("文件上传")
    18. @PostMapping("/upload")
    19. public String upLoadFile(MultipartFile uploadFile) throws IOException {
    20. //1.创建文件存储目录(使用年月日结构进行存储)
    21. String dateStr = DateTimeFormatter.ofPattern("yyyy/MM/dd").format(LocalDate.now());
    22. //1.2创建文件上传对象
    23. File uploadDir = new File(resourcePath, dateStr);
    24. if (!uploadDir.exists()) {
    25. uploadDir.mkdirs();
    26. }
    27. //2.修改文件名称使其名称唯一
    28. String originalFilename = uploadFile.getOriginalFilename();
    29. //2.1构建文件前缀
    30. String filePrefix = UUID.randomUUID().toString();
    31. //2.2获取文件后缀
    32. String fileSuffix = originalFilename.substring(originalFilename.lastIndexOf("."));
    33. String newFileNme = filePrefix + fileSuffix;
    34. log.debug("新文件名为:" + newFileNme);
    35. //3.上传文件到指定目录
    36. uploadFile.transferTo(new File(uploadDir, newFileNme));
    37. //4.返回通过http协议可以访问到文件路径
    38. String accessAddress = resourceHost + dateStr + "/" + newFileNme;
    39. log.debug("上传地址为:{}",accessAddress);
    40. return accessAddress;
    41. }
    42. }
  2. 执行指定切入点的方法,进行拓展业务实现

    1. @Slf4j
    2. @Component
    3. @Aspect
    4. public class LogAspect {
    5. /**
    6. * 在执行的切入点方法上执行@Around注解描述的方法
    7. *
    8. * @param jp 连接点(期内封装所要执行的链信息,包括目标方法信息)
    9. * @return 目标方法的返回值
    10. */
    11. @Around("doLog()")
    12. public Object doAround(ProceedingJoinPoint jp) throws Throwable {
    13. log.info("Around.Before:{}", System.currentTimeMillis());
    14. //执行目标执行链(包含切面,目标方法)
    15. Object result = jp.proceed();
    16. log.info("Around.After:{}", System.currentTimeMillis());
    17. return result;
    18. }
    19. }