Spring AOP应用 --记录用户的操作轨迹
1.需求:
记录展示每款产品的操作路径,操作账号,操作时间,便于管理。 解决:采用AOP结合自定义注解来实现记录用户的操作轨迹
2.代码实现:
AOP:
在面向切面编程的思想里面,把功能分为核心业务功能和周边功能。周边功能在Spring的面向切面编程AOP思想里,即被定义为切面。
核心业务功能和切面功能分别独立进行开发,然后把切面功能和核心业务功能 "编织" 在一起,这就叫AOP。
1.自定义注解: 由于只是记录在哪个分类下做了什么操作,
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface Operation { String category() default "";//分类 String type() default ""; //操作 }
1 //分类属性值 2 public final class OperationCategory { 3 4 public static final String ALL= "全部"; 5 public static final String SLIDE_SHOW="轮播图"; 6 public static final String FEATURED_FIRST="推荐位"; 7 public static final String PRODUCT_LIST="产品列表"; 8 9 }
1 //操作属性值 2 public class OperationType { 3 4 public static final String NEWLY_INCREASED="新增"; 5 public static final String ADD="添加"; 6 public static final String UPDATE ="修改"; 7 public static final String PUTWAY_OR_SOLD_OUT ="上架/下架"; 8 // public static final String SOLD_OUT= "下架"; 9 public static final String DELETE= "删除"; 10 public static final String MOVE_UP= "上移"; 11 public static final String MOVE_DOWN= "下移"; 12 public static final String IS_TOP= "置顶"; 13 }
2.切面:
1 @Aspect 2 @Component 3 public class OperationAspect { 4 5 @Autowired 6 OperatorTrajectoryService operatorTrajectoryService; 7 8 @Autowired 9 CommodityCombinationMapper commodityCombinationMapper; 10 11 @Autowired 12 AdvertiseInfoMapper advertiseInfoMapper; 13 14 @Autowired 15 private HrpProductListInfoMapper hrpProductListInfoMapper; 16 17 @Autowired 18 private ProductInfoMapper productInfoMapper; 19 20 /** 21 * 定义切点 带有Operation注解的方法 都会被切入 22 */ 23 @Pointcut("@annotation(com.tit.insurance.management.annotion.Operation)") 24 public void operate() { 25 } 26 27 //执行 若使用注解的属性值 加上@annotation(operation) 28 @After("operate()&&@annotation(operation)") 29 public void doAfter(JoinPoint joinPoint, Operation operation) { 30 System.out.println("******拦截后的逻辑******"); 31 32 // 获取传入目标方法的参数 33 Object[] args = joinPoint.getArgs(); 34 for (int i = 0; i < args.length; i++) { 35 System.out.println("第" + (i + 1) + "个参数为:" + args[i]); 36 } 37 //传入的参数是:广告、产品、推荐产品 38 if (args[0] instanceof AdvertiseInfo) { 39 AdvertiseInfo advertiseInfo = (AdvertiseInfo) args[0]; 40 OperationTrajectory operationTrajectory = new OperationTrajectory(); 41 operationTrajectory.setCategory(operation.category()); 42 operationTrajectory.setOperationAccount( 43 SecurityUtil.currentUser() == null ? "admin" : SecurityUtil.currentUser().getUsername()); 44 if (operation.type().equals(OperationType.PUTWAY_OR_SOLD_OUT)) { 45 operationTrajectory.setOperationType("0".equals(advertiseInfo.getIsUse()) ? "下架" : "上架"); 46 } 47 else { 48 operationTrajectory.setOperationType(operation.type()); 49 } 50 if (advertiseInfo.getId() != null) { 51 // 根据id查询指定软文信息 52 advertiseInfo = advertiseInfoMapper.selectByPrimaryKey(advertiseInfo.getId()); 53 if (advertiseInfo.getCommodityCombinationId() != null) { 54 operationTrajectory.setProductCode(String.valueOf(advertiseInfo.getCommodityCombinationId())); 55 operationTrajectory.setProductName(advertiseInfo.getLinkTitle()); 56 } 57 } 58 operationTrajectory.setOperationTime(new Date()); 59 operatorTrajectoryService.addOperation(operationTrajectory); 60 } 61 else if (args[0] instanceof HrpProductListInfo) { 62 HrpProductListInfo productListInfo = (HrpProductListInfo) args[0]; 63 OperationTrajectory operationTrajectory = new OperationTrajectory(); 64 operationTrajectory.setCategory(operation.category()); 65 operationTrajectory.setOperationAccount( 66 SecurityUtil.currentUser() == null ? "admin" : SecurityUtil.currentUser().getUsername()); 67 if (operation.type().equals(OperationType.PUTWAY_OR_SOLD_OUT)) { 68 operationTrajectory.setOperationType("0".equals(productListInfo.getIsUse()) ? "下架" : "上架"); 69 } 70 else { 71 operationTrajectory.setOperationType(operation.type()); 72 } 73 if (productListInfo.getId() != null) { 74 // 根据id查询指定软文信息 75 HrpProductListInfo hrpProductListInfo = hrpProductListInfoMapper 76 .selectByPrimaryKey(productListInfo.getId()); 77 if (hrpProductListInfo != null) { 78 operationTrajectory.setProductCode(hrpProductListInfo.getProductCode()); 79 operationTrajectory.setProductName(hrpProductListInfo.getProductName()); 80 } 81 } 82 operationTrajectory.setOperationTime(new Date()); 83 operatorTrajectoryService.addOperation(operationTrajectory); 84 } 85 else if (args[0] instanceof ProductInfo) { 86 ProductInfo productInfo = (ProductInfo) args[0]; 87 OperationTrajectory operationTrajectory = new OperationTrajectory(); 88 operationTrajectory.setCategory(operation.category()); 89 operationTrajectory.setOperationAccount( 90 SecurityUtil.currentUser() == null ? "admin" : SecurityUtil.currentUser().getUsername()); 91 if (operation.type().equals(OperationType.PUTWAY_OR_SOLD_OUT)) { 92 operationTrajectory.setOperationType("0".equals(productInfo.getIsUse()) ? "下架" : "上架"); 93 } 94 else { 95 operationTrajectory.setOperationType(operation.type()); 96 } 97 if (productInfo.getId() != null) { 98 // 根据id查询指定软文信息 99 productInfo = productInfoMapper.selectByPrimaryKey(productInfo.getId()); 100 operationTrajectory.setProductCode(productInfo.getProductCode()); 101 operationTrajectory.setProductName(productInfo.getProductName()); 102 } 103 operationTrajectory.setOperationTime(new Date()); 104 operatorTrajectoryService.addOperation(operationTrajectory); 105 } 106 } 107 }
3.在需要编织的地方 加上自定义注解:
1 /** 2 * 广告新增 3 * 4 * @param req 5 * @param resp 6 */ 7 @PostMapping("/addAdver") 8 @ResponseBody 9 //***********加上该自定义注解******** 10 @Operation(category = OperationCategory.SLIDE_SHOW, type = OperationType.ADD) 11 public Status addAdverInfo(@RequestBody AdvertiseInfo advertiseInfo) { 12 Status status = new Status(); 13 try { 14 advertiseService.addAdver(status, advertiseInfo); 15 } 16 catch (Exception e) { 17 status.setStatusCode("0"); 18 status.setStatusMessage("【增加广告】参数解析异常!!!"); 19 log.error("app新增广告失败!!!" + e.getMessage()); 20 } 21 status.setTransTime(DateTime.getTimeString()); 22 return status; 23 }
这样每当用户新增广告时候,aop就会记录向表中增加该条操作记录信息。