• AOP切面类使用代码


    各个注解方法执行顺序

    @Around注解方法的前半部分业务逻辑->@Before注解方法的业务逻辑->目标方法的业务逻辑
    ->@Around注解方法的后半部分业务逻辑(@Around注解方法内的业务逻辑若对ProceedingJoinPoint.proceed()方法没做捕获异常处理,直接向上抛出异常,则不会执行Around注解方法的后半部分业务逻辑;若做了异常捕获处理,则会执行)。
    ->@After(不管目标方法有无异常,都会执行@After注解方法的业务逻辑)
    ->@AfterReturning(若目标方法无异常,执行@AfterReturning注解方法的业务逻辑)
    ->@AfterThrowing(若目标方法有异常,执行@AfterThrowing注解方法的业务逻辑)
     

    环绕通知@Around使用

    1. /**
    2. * 此方法必须有返回值,否则目标方法无法拿到执行结果
    3. * @param point
    4. * @return
    5. */
    6. @Around("execution(* com.test.resultFacade..*(..))")
    7. public Object checkContactInfoUpdateBefore(ProceedingJoinPoint point){
    8. log.info("目标方法前执行");
    9. Object result = null;
    10. try {
    11. // 执行目标方法
    12. result = point.proceed();
    13. log.info("result:",JSONObject.toJSONString(result));
    14. } catch (Throwable throwable) {
    15. throwable.printStackTrace();
    16. }
    17. log.info("目标方法后执行");
    18. return result;
    19. }

    aspect各个方法的使用案例说明

    1. @Aspect
    2. @Slf4j
    3. public class MessageAspect {
    4. /**
    5. * 方式一:使用表达式,满足此注解的方法即会执行切面方法
    6. * 1.本类引用
    7. * 2.其他的切面引用
    8. */
    9. @Pointcut("execution(public Integer com.xiaoz.aop.calculator.dev(int,int))")
    10. public void poincut(){
    11. }
    12. /**
    13. * 方式二:使用主键方式,标注此注解的方法即会执行切面方法
    14. * 1.本类引用
    15. * 2.其他的切面引用
    16. */
    17. @Pointcut("@annotation(com.xiaoz.annotation.MessageAnnotation)")
    18. public void pointcut() {
    19. }
    20. /**
    21. * around切面方法,引用本类中的公用的pointcut
    22. * @param point
    23. * @return
    24. * @throws Throwable
    25. */
    26. @Around("Pointcut()")
    27. public Object process(ProceedingJoinPoint point) throws Throwable {
    28. System.out.println("@Around:执行目标方法之前...");
    29. //访问目标方法的参数:
    30. Object[] args = point.getArgs();
    31. if (args != null && args.length > 0 && args[0].getClass() == String.class) {
    32. args[0] = "改变后的参数1";
    33. }
    34. //用改变后的参数执行目标方法
    35. Object returnValue = point.proceed(args);
    36. System.out.println("@Around:执行目标方法之后...");
    37. System.out.println("@Around:被织入的目标对象为:" + point.getTarget());
    38. return "原返回值:" + returnValue + ",这是返回结果的后缀";
    39. }
    40. /**
    41. * 引用其他外部切面类的切入点公用方法
    42. */
    43. @After(com.xiaoz.other.LogAspect.pointCut())
    44. public void logEnd(){
    45. log.info("执行代码");
    46. }
    47. @Before("execution(* com.abc.service.*.many*(..))")
    48. public void permissionCheck(JoinPoint point) {
    49. System.out.println("@Before:模拟权限检查...");
    50. System.out.println("@Before:目标方法为:" +
    51. point.getSignature().getDeclaringTypeName() +
    52. "." + point.getSignature().getName());
    53. System.out.println("@Before:参数为:" + Arrays.toString(point.getArgs()));
    54. System.out.println("@Before:被织入的目标对象为:" + point.getTarget());
    55. }
    56. /**
    57. * 在所有标记了@SMSAndMailSender的方法中切入
    58. * @param joinPoint
    59. * @param result
    60. */
    61. @AfterReturning(value="@annotation(com.trip.demo.SMSAndMailSender)", returning="result")
    62. public void afterReturning(JoinPoint joinPoint , Object result//注解标注的方法返回值) {
    63. MethodSignature ms = (MethodSignature) joinPoint.getSignature();
    64. Method method = ms.getMethod();
    65. boolean active = method.getAnnotation(SMSAndMailSender.class).isActive();
    66. if (!active) {
    67. return;
    68. }
    69. String smsContent = method.getAnnotation(SMSAndMailSender.class).smsContent();
    70. String mailContent = method.getAnnotation(SMSAndMailSender.class).mailContent();
    71. String subject = method.getAnnotation(SMSAndMailSender.class).subject();
    72. }
    73. /**
    74. * 在抛出异常时使用 SMSAndMailSender为自定义注解,所有标注此注解的业务方法都会触发此切面方法
    75. * @param joinPoint
    76. * @param ex
    77. */
    78. @AfterThrowing(value="@annotation(com.xiaoz.SMSAndMailSender)",throwing = "ex")
    79. public void afterThrowing(JoinPoint joinPoint, Throwable ex//注解标注的方法抛出的异常) {
    80. MethodSignature ms = (MethodSignature) joinPoint.getSignature();
    81. Method method = ms.getMethod();
    82. String subject = method.getAnnotation(SMSAndMailSender.class).subject();
    83. }
    84. }

    使用annotation生产代码案例

    自定义注解

    1. @Target({ElementType.METHOD})
    2. @Retention(RetentionPolicy.RUNTIME)
    3. @Documented
    4. public @interface MessageAnnotation {
    5. InteractionTopicEnum value();
    6. }

    自定义枚举类

    1. @Getter
    2. @AllArgsConstructor
    3. public enum InteractionTopicEnum {
    4. ORDER(1, "下单完成"),
    5. ORDER_PAY(2, "支付完成"),;
    6. private Integer key;
    7. private String value;
    8. }

     业务方法标注切面方法

    1. @Transactional
    2. @MessageAnnotation(InteractionTopicEnum.ORDER)
    3. public BaseDtoResponse creatOrder(){
    4. // 执行业务代码
    5. }

    切面类方法

    1. @Aspect
    2. @Slf4j
    3. public class MessageAspect {
    4. @Pointcut("@annotation(com.xiaoz.annotation.MessageAnnotation)")
    5. public void pointcut() {
    6. }
    7. @Before("pointcut()")
    8. public void permissionCheck(JoinPoint point) {
    9. // 执行切入方法
    10. }
    11. }

  • 相关阅读:
    redis持久化RDB和AOF的区别;以及AOF的重写
    2022年全国最新消防设施操作员(中级消防设施操作员)真题题库及答案
    idm序列号永久激活码2023免费可用 IDM软件破解版下载 最新版Internet Download Manager 网络下载加速必备神器 IDM设置中文
    家电生产线数控机床上下料长臂机器人组设计
    井字棋游戏
    数据库优化
    WZOI-210收集金币
    Java——聊聊JUC中的CAS原理
    2022年最新四川水利水电施工安全员模拟试题题库及答案
    企业如何降低销售成本?快鲸scrm系统帮您实现
  • 原文地址:https://blog.csdn.net/qq_36042938/article/details/126704361