原因:

  以前学习Spring的时候着重学习过AOP概念,但是一直也没有用上,唯一碰到过的就是Spring内置的事务管理。现在碰到过一些结果后面的操作适合用到,所以这里就拿出来用一下,并且复习一下落下的知识。

概念:

  基本概念这个博主解释的比较清楚,如果有不懂的可以去看一下。https://blog.csdn.net/csh624366188/article/details/7651702

  在我的认识里,如果某些方法重复性特别高,可以抽象出来形成一个切面,则可以使用AOP来简化代码,即在方法的某些部分动态的添加某些方法,起到简化代码的作用。

具体需求:

  项目的Service层通过webService获取到数据,需要对获取到的数据进行判断处理,对其异常信息作出记录和抛出异常。同时还需要在进入和结束方法的时候进行日志记录。

知识点:

  配置方法:

  在这里使用的是注解的方式来配置的AOP,首先,要保证项目中除了Spring基本包以外还包含aopalliance-1.0.jar,aspectjrt-1.8.7.jar,aspectjweaver-1.8.7.jar,cglib-nodep-3.2.4.jar这四个jar包,这里将其打包放到百度云,如果有需要的可以去下载。链接:https://pan.baidu.com/s/1rDqLY1lnWdiahVkLcZd_bw 密码:0uea

  Spring配置添加如下, 添加<aop:aspectj-autoproxy />需要添加Spring的头部内容

  注意aop不能添加到static方法上面。

  1. <aop:aspectj-autoproxy /> // 扫描AOP
  2. <!-- 这里配置后就不用再使用bean标签配置bean了 -->
  3. <context:annotation-config></context:annotation-config>
  4. <!-- 去哪个包扫描生成bean -->
  5. <context:component-scan base-package="com.dazhong.jnfy.alipay.action" />

  首选建立切面类:其中的afterReturning就是主要的切面方法,用于对返回值进行判断并且进行对应的操作,这样可以不用再每个方法中都写一次。

  1.   
  1.   @Pointcut("execution(* com.dazhong.jnfy.alipay.service.impl.*.*(..))"):表示AOP会代理那些方法,这里则表示com.dazhong.jnfy.alipay.service.impl包下面所有方法都会执行
  1.   @After("picter()"):后置通知
  1.   @Before("picter()"):前置通知
  1.  
  1. package com.dazhong.jnfy.alipay.aop;
  2.  
  3. import org.aspectj.lang.JoinPoint;
  4. import org.aspectj.lang.annotation.After;
  5. import org.aspectj.lang.annotation.AfterReturning;
  6. import org.aspectj.lang.annotation.Aspect;
  7. import org.aspectj.lang.annotation.Before;
  8. import org.aspectj.lang.annotation.Pointcut;
  9. import org.json.JSONObject;
  10. import org.springframework.stereotype.Component;
  11.  
  12. import com.dazhong.jnfy.alipay.exception.ConnectionException;
  13. import com.dazhong.jnfy.alipay.exception.ResultErrorException;
  14. import com.dazhong.utils.LogUtil;
  15.  
  16. @Component
  17. @Aspect
  18. public class ServiceAop {
  19.  
  20. @Pointcut("execution(* com.dazhong.jnfy.alipay.service.impl.*.*(..))")
  21. public void picter() {
  22. }
  23.  
  24. /**
  25. * @Description: 对返回值进行处理
  26. * @param point
  27. * @param rvt
  28. * @throws ResultErrorException
  29. */
  30. @AfterReturning(returning = "rvt", pointcut = "execution(* com.dazhong.jnfy.alipay.service.impl.*.*(..))")
  31. public void afterReturning(JoinPoint point, Object rvt) throws Exception { // Object rvt则是方法返回值,这里变量名称要和注解retruning值相同
  32. String[] strs = point.getSignature().getDeclaringTypeName().split("\\.");
  33. String fullname = strs[strs.length - 1] + "." + point.getSignature().getName();
  34.  
  35. JSONObject root = (JSONObject) rvt;
  36.  
  37. if (rvt == null) {
  38. throw new ConnectionException("WebService连接失败" + fullname);
  39. } else if (!root.has("resultCode") || !root.get("resultCode").toString().equals("0")) {
  40. // 返回数据异常
  41. throw new ResultErrorException("WebService 返回结果异常:" + root.toString());
  42. }
  43. }
  44.  
  45. @Before("picter()")
  46. public void before(JoinPoint point) {
  47. String[] strs = point.getSignature().getDeclaringTypeName().split("\\.");
  48. String fullname = strs[strs.length - 1] + "." + point.getSignature().getName();
  49. LogUtil.info("进入方法:" + fullname);
  50. }
  51.  
  52. @After("picter()")
  53. public void after(JoinPoint point) {
  54. String[] strs = point.getSignature().getDeclaringTypeName().split("\\.");
  55. String fullname = strs[strs.length - 1] + "." + point.getSignature().getName();
  56. LogUtil.info("方法结束:" + fullname);
  57. }
  58.  
  59. }

  获取参数/方法名:

    如果需要获取目标方法的参数/名字,则需要在切面的方法中添加变量 JoinPoint point,通过这个对象来进行获取。

  1. String allname = point.getSignature().getDeclaringTypeName(); // 获取整个路径 包名+类名
  2. System.out.println(allname);
  3. String[] split = allname.split("\\.");
  4. System.out.println("目标方法:" + split[split.length - 1] + "." + point.getSignature().getName()); // point.getSignature().getName() 获取方法名
  5. System.out.println("@Before:参数为:" + Arrays.toString(point.getArgs())); // 获取目标方法的参数 point.getArgs()

  结果: 红框内容就是AOP自动添加的。

  

 剩余代码:

  目标方法:

  

  1. public JSONObject test() throws Exception{
  2. System.out.println("目标方法执行");
  3. JSONObject js = new JSONObject();
  4. js.put("resultCode", "-1");
  5. return js;
  6. }

  测试方法:

  

  1. public static void main(String[] args) {
  2. ApplicationContext appCtx = new ClassPathXmlApplicationContext("applicationContext.xml");
  3. ReserveServiceImpl b = (ReserveServiceImpl) appCtx.getBean("reserveServiceImpl");
  4. JSONObject js = new JSONObject();
  5. js.put("s", "111");
  6. try {
  7. //JSONObject allDept = b.getDocterByTimeAndDept("YYKS002", "20180711");
  8. b.test();
  9. } catch (Exception e) {
  10. System.out.println(e);
  11. }
  12. }

  

AOP的具体实践-简化结果返回的处理的更多相关文章

  1. AOP的姿势之 简化 MemoryCache 使用方式

    0. 前言 之前写了几篇文章介绍了一些AOP的知识, 但是还没有亮出来AOP的姿势, 也许姿势漂亮一点, 大家会对AOP有点兴趣 内容大致会分为如下几篇:(毕竟人懒,一下子写完太累了,没有动力) AO ...

  2. AOP的姿势之 简化混用 MemoryCache 和 DistributedCache 的方式

    0. 前言 之前写了几篇文章介绍了一些AOP的知识, 但是还没有亮出来AOP的姿势, 也许姿势漂亮一点, 大家会对AOP有点兴趣 内容大致会分为如下几篇:(毕竟人懒,一下子写完太累了,没有动力) AO ...

  3. Unity应用架构设计(12)——AOP思想的实践

    想象一下,当程序所有的业务逻辑都完成的时候,你可能还来不及喘口气,紧张的测试即将来临.你的Boss告诉你,虽然程序没问题,但某些方法为什么执行这么慢,性能堪忧.领会了Boss的意图之后,漫长的排查问题 ...

  4. C# 中使用面向切面编程(AOP)中实践代码整洁

    1. 前言 最近在看<架构整洁之道>一书,书中反复提到了面向对象编程的 SOLID 原则(在作者的前一本书<代码整洁之道>也是被大力阐释),而面向切面编程(Aop)作为面向对象 ...

  5. Spring Aop 修改目标方法参数和返回值

    一.新建注解 @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Document ...

  6. C# 中使用面向切面编程(AOP)中实践代码整洁(转)

    出处:https://www.cnblogs.com/chenug/p/9848852.html 1. 前言 最近在看<架构整洁之道>一书,书中反复提到了面向对象编程的 SOLID 原则( ...

  7. AOP打印请求日志,打印返回值

    @Aspect // 申明是个spring管理的bean @Component @Slf4j public class LogAspectServiceApi { private JSONObject ...

  8. Spring 学习二-----AOP的原理与简单实践

    一.Spring  AOP的原理 AOP全名Aspect-Oriented Programming,中文直译为面向切面(方面)编程.何为切面,就比如说我们系统中的权限管理,日志,事务等我们都可以将其看 ...

  9. ASP.NET Core WebApi返回结果统一包装实践

    前言 近期在重新搭建一套基于ASP.NET Core WebAPI的框架,这其中确实带来了不少的收获,毕竟当你想搭建一套框架的时候,你总会不自觉的去想,如何让这套框架变得更完善一点更好用一点.其中在关 ...

随机推荐

  1. WPF备忘录(7)WPF图片资源路径介绍

    在项目中增加两张图片Content.jpg和Resource.jpg,分别将其生成操作属性设置为Content和Resource.     在界面中增加两个Image控件ImgContent和ImgR ...

  2. 面试7 GC机制中如何判断一个对象是否任在使用

    GC 通过在使用的根引用遍历所有引用的对象实例,当一个对象不能被遍历时,将被视为不能被使用.

  3. 使用jQuery和CSS3制作数字时钟(jQuery篇) 附源码下载

    HTML 和上一篇文章:使用jQuery和CSS3制作数字时钟(CSS3篇)一样的HTML结构,只是多了个>date用来展示日期和星期的. <div id="clock" ...

  4. 《码出高效 Java开发手册》第六章 数据结构与集合

    码云: https://gitee.com/forxiaoming/JavaBaseCode/blob/master/EasyCoding/src/collection/index.md 6.1 数据 ...

  5. hdu 2612

    Find a way Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  6. element ui 时间控件 多个日期

    前言:工作中用到 vue+element ui 的前端框架,需要使用时间控件来选择多个日期,已月日的形式,且有默认值,所以记录一下.转载请注明出处:https://www.cnblogs.com/yu ...

  7. WCF使用net.tcp绑定的配置实例

    <system.serviceModel> <bindings> <basicHttpBinding> <!--默认http绑定的配置,这里提高了最大传输信息 ...

  8. 修改input被选中的默认样式

    input:focus{    outline: none;     border: 1px solid #fff; } 或者 input[type=text]:focus{   outline: n ...

  9. springboot中使用自定义的properties属性

    在application.properties中添加属性ai.name=明ai.age=22ai.sex=男定义配置类如下,前缀(prefix)可自定义修改,本文为 ai.@Configuration ...

  10. vue三要素及底层实现机制

    深入解析Vue 我们首先来熟悉一下我们这个文档所学习内容的流程. 先对比一下jQuery和Vue的区别,再讲述Vue的MVVM模型,接着讲解Vue的实现流程. 当然,我是不相信没有对比哪来的伤害,没有 ...