【58】

前面讲解了spring的特性之一,IOC(控制反转),因为有了IOC,所以我们都不需要自己new对象了,想要什么,spring就给什么。而今天要学习spring的第二个重点,AOP。

一、什么是AOP

  AOP:面向切面编程,采用横向抽取机制,取代了传统的纵向继承

  IOC:控制反转     

  跟IOC一样,我也不知道,这么高大上的名称,被吓坏了,MD,但是通过前面一节的学习,IOC不就是让spring给我们new对象吗,而不需要我们自己创建,

  而AOP是一种面向切面的思想,但是我们平常说的spring使用了AOP,实际上说的是spring实现AOP思想的底层原理,而底层原理就是使用动态代理来增强某个方法。所以平常说AOP技术实际上就是指通过动态代理来对方法进行增强。比如:我们需要对一个已经写好的类中的方法进行增强,在不改动该类方法的代码的情况下,如何做呢?

传统纵向继承

  编写一个类,继承该类,重写该类中的这种需要增强的方法,这样确实可以达到我们的目的,但是一旦需要修改的方法所属的类不是一个类,那么就需要在多写很多子类,增加很多方法,编程量就是一个很大的问题,并且后期要修改,工作量也很大。

横向抽取机制,将要增强所用到的代码提取到一个类中,然后对需要增强的方法通过代理类去将其增强即可。

二、动态代理的两个方式

      JDK动态代理。接口+实现类

      cglib字节码增强。 实现类

      为了更好的理解spring的AOP技术,我们应该手动编写以上两种实现动态代理的方法,然后才能体会到spring实现AOP技术所带来的便利。

2.1、JDK动态代理。

          要使用JDK动态代理的类,必须要有接口。这是前提条件。

          编写UserService接口和UserServiceImpl。

          创建代理类的工厂proxyFactory

 增强代码的类

测试testApp

  测试结果 成功增强了userServiceImpl对象的add方法。如果别的类有需要被增强的方法,那么同样通过创建工厂代理就可以拿到对应的代理对象。然后进行加强

2.2 cglib动态代理。

  被代理的对象不需要在实现接口,要求就放松了很多。很多时候都采用cglib来进行动态代理。

  需要导入两个jar包

spring已经将cglib和asm整合到了spring-core-3.2.0.jar中,所以我们导入spring的jar包就不需要在重复导这两个包了。

跟JDK动态代理的编写流程是一样的

UserServiceImpl。没有接口了

增强方法的类

创建代理的工厂(和jdk动态代理有区别)

   测试

   成功增强方法。

   注意:CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑,所以  说被代理的类不能有final关键字

三、spring中使用AOP的相关术语

  3.1、Target:目标类,需要被增强的类,也就是上面我们写的UserServiceImpl。

  3.2、JointPoint:连接点,目标类上需要被增强的方法,(这些方法可以被增强,也可以不增强,也就是说目标类中所有的方法都可以称为是连接点)

  3.3、PointCut:切入点,被增强的方法(已经确定这个方法要被增强),切入点就是一个连接点的子集

  3.4、Advice:增强/通知,增强的代码,也就是上面将增强的代码凑成的一个类。类中的每个方法都代表一个增强的功能代码,这个类中的方法就被称为通知

  3.5、weaving:织入,将切入点和通知结合,从没被增强到已经增强的过程

  3.6、Aspect:切面,切入点和通知结合,切入点 和 通知点 多点形成面  特殊情况:一个切入点 和 一个通知

画张图就可以理解了。

3.7、Introduction(引介) 特殊的通知,可以对类增强,添加方法或字段。(知道)

四、spring如何帮我们实现AOP技术(初级版)

       spring创建代理工厂bean,属于半自动,思路跟我们用JDK动态代理和cglib动态代理是一样的,只是spring通过ioc帮我们创建这些对象,工厂也是由spring提供。唯一的不同是,我们编写的通知类(之后将其叫成切面类,也就是放增强的代码方法的类) 必须实现MethodInterceptor(注意导包时的问题,这个名称跟cglib中的那个一样,不要导错了)接口,并实现invoke方法,这里就是编写如何增强切入点,好比上面jdk动态代理和cglib代理中的匿名内部类中的方法一样。具体下面讲解。

       导入jar包

          spring : 4个核心 + 1个依赖

          spring aop联盟:

          spring aop 实现:

       UserServiceImpl

MySpect 切面类,

 applicationcontext.xml。

这里注意,如果没有接口,那么其中必须使用3.4的代码也就是34行的代码,必须告诉spring,使用cglib进行代理,否则出错。

测试

总结:这种方式属性半自动的,需要配置工厂bean,并且目标类的确定太小了,每次只能指定一个目标类,如果我们想对别的类也进行加强,那么就需要在工厂bean中又配置一个目标类,这就体现不出spring的优势了。不推荐使用这种。了解整个发展过程即可

五、spring实现AOP技术(中级 掌握)

全自动过程。直接覆盖很多目标类,不需要在一个个对目标类进行编写通知和工厂了。

其他都一样,配置文件不一样。切入点就不单单是一个目标类了。而是一个范围。

切面类还是跟上面一样

测试: 成功

  总结:相比初级的aop实现,好的地方在不用在自己设置工厂bean了,还在直接大范围的指定代理目标类,而不是一个类只能被指定一次。这就是全自动,不用我们配置工厂bean

,spring帮我们都做好了。我们只需要关注切面类,也就是通知和切入点的结合即可。

六、使用AspectJ框架(xml方式)实现aop(高级,推荐)

   使用这个的好处在于,我们都不需要在切面类中实现什么通知类型接口了,通知类型接口也在配置文件中编写,而切面类只要关注增强的方法代码即可。并且不管业务类是否实现接口,编写的代码都是一样的,如果实现了接口。AspectJ框架会使用jdk代理,如果没有实现接口,则使用cglib代理,这两者之间相互转换。而spring内置的aop技术则需要自己手动去设置,默认是jdk,如果没有接口,不会自动帮我们转换。

   导包:新增两个aspect支持的jar包

    aop联盟:com.springsource.org.aopalliance-1.0.0.jar

  spring aop支持:spring-aop-3.2.0.RELEASE.jar

   aspect 规范:com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

  spring aspect 支持:spring-aspects-3.2.0.RELEASE.jar

AspectJ规定通知类型

1.before:前置通知(应用:各种校验) 在方法执行前执行,如果通知抛出异常,阻止方法运行

2.afterReturning:后置通知(应用:常规数据处理)方法正常返回后执行,如果方法中抛出异常,通知无法执行必须在方法执行后才执行,所以可以获得方法的返回值。

 3.around:环绕通知(应用:十分强大,可以做任何事情) 【掌握】方法执行前后分别执行,可以阻止方法的执行。要求必须手动的执行目标方法。

4.afterThrowing:抛出异常通知(应用:包装异常信息) 方法抛出异常后执行,如果方法没有抛出异常,无法执行

5.after:最终通知(应用:清理现场) 方法执行完毕后执行,无论方法中是否出现异常

配置文件

通知类型的详解

 切面类

 测试:

总结:使用AspectJ框架实现AOP,好处很多,关注的点只有切面类(不需要实现通知类型接口),切入点范围,还有通知类型。所以在配置文件中,也只需要配置这三个关键的东西即可,具体看上面的配置文件

七、使用AspectJ框架(注解方式)实现aop(高级,推荐)

   使用注解的话,很简单,就是把xml方式用注解给替代,其中也就做6件事

1、将切面类配置给spring,相当于<bean id="" class="切面类全限定类名">

     @component

2、将切面类申明为切面

     @Aspect

3、将目标类配置给spring

    @component  如何不编写名称的话,那么要获取该对象,则使用userServiceImpl进行获取。

4、申明目标类切入点范围

    1.方法必须private,没有返回值,没有参数

    2.之后使用将其当成方法调用。例如:@After("myPointcut()") 

    @Pointcut("execution(* com.wuhao.aspectj.annotation.*.*(..))")

5、编写相应的通知           

   @Before 前置

   @AfterReturning 后置,可以获得返回值,必须在注解中确定返回值参数名称。

   @AfterThrowing 抛出异常,可以获得具体异常信息,必须在注解确定第二个参数名称

   @Around 环绕[]

   @After 最终  

6:必须在xml中扫描注解和启用aop

7、测试

总结;注解的编写也很简单,要会写注解,首先的知道xml是如何实现的,然后一步步用注解来替代xml的内容即可。并且要知道使用AspectJ框架需要配置哪些内容,就三个点,

xml:

   目标类bean

   切面类bean   

<aop:config>

八、总结

   基本上把spring中使用AOP的技术讲清楚了,这一篇相等于写一个aop的helloworld一样,下面还会对spring中使用AOP的技术进一步讲解。

aop实现原理_Spring学习之AOP相关推荐

  1. 在Intellij上面导入项目 AOP示例项目 AspectJ学习 Spring AoP学习

    为了学习这篇文章里面下载的代码:http://www.cnblogs.com/charlesblc/p/6083687.html 需要用Intellij导入一个已有工程.源文件原始内容也可见:link ...

  2. aop实现原理_Dubbo SPI中AOP实现原理

    官网:http://dubbo.apache.org/zh-cn/docs/2.7/source_code_guide/dubbo-spi/ 从官网说明中我们可以看到,dubbo spi是java s ...

  3. spring aop实现原理_Spring 异步实现原理与实战分享

    最近因为全链路压测项目需要对用户自定义线程池 Bean 进行适配工作,我们知道全链路压测的核心思想是对流量压测进行标记,因此我们需要给压测的流量请求进行打标,并在链路中进行传递,那么问题来了,如果项目 ...

  4. ppst——技术视频spring AOP 的原理讲解和简单实现

    ppst 技术视频--spring AOP 的原理讲解和简单实现:请访问ppst 技术视频分享平台 , www.ppst.cc,上面有最新的技术视频,推荐大家把博客录制成视频吧,可以获取收益哦 1.s ...

  5. spring 测试demo乱码_spring框架的入门学习:AOP和面向切面的事务

    使用注解配置spring,需要以下几个步骤: 需要导入一个包: 步骤1:需要为主配置文件引入新的命名空间(约束),和之前介绍的一样,导入新的约束: 然后在application.xml的Design中 ...

  6. spring aop原理_Spring知识点总结!已整理成142页离线文档(源码笔记+思维导图)...

    写在前面 由于Spring家族的东西很多,一次性写完也不太现实.所以这一次先更新Spring[最核心]的知识点:AOP和IOC 无论是入门还是面试,理解AOP和IOC都是非常重要的.在面试的时候,我没 ...

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

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

  8. spring aop 必须的包 及里面用到的东西_Spring 原理初探——IoC、AOP

    前言 众所周知, 现在的 Spring 框架已经成为构建企业级 Java 应用事实上的标准了,众多的企业项目都构建在 Spring 项目及其子项目之上,特别是 Java Web 项目. Spring ...

  9. Java:由浅入深揭开 AOP 实现原理

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:干掉 Navicat:这个 IDEA 的兄弟真香!个人原创100W+访问量博客:点击前往,查看更多 作者:马佩 ...

  10. aop实现原理-动态代理CGLib代理

    那接下来的话,那咱们Spring当中,这个AOP,咱们先说概念,咱们先不写具体代码,咱们就是聊,聊Spring的AOP,Spring能帮我们干啥呢,我告诉你,Spring他作为对象的容器,Spring ...

最新文章

  1. JDK和JRE的区别-zz
  2. JQuery图表插件Highcharts示例教程
  3. python递归函数特点_python中对递归函数的理解
  4. turtle库基础练习
  5. 秒后面的单位是什么_为什么兰州马拉松很难跑出好成绩?
  6. Magento教程 12:Magento快速上传大量商品的方法
  7. 利用cookies实现对弹出窗口频率的控制
  8. pytorch1.0神经网络保存、提取、加载
  9. python定义一个circle类、根据圆的半径_定义一个“圆”类Circle,该圆类的数据成员包括:圆心点位置及圆的半径...
  10. 程序运行中(BSS段、数据段、代码段、堆栈)
  11. 阿里云linux上安装,卸载mysql与重新安装配置Mysql
  12. 未找到uniwebview_UniWebView.dll
  13. git使用中遇到的remote:Permission to xxx denied to xxx问题如何解决报错403找不到的问题
  14. 京享值超8万的京东钻石用户告诉你套路是这样的
  15. log4j 使用记录
  16. 在cmd命令下imp oracle dmp文件
  17. 照片尺寸像素怎么调?在线改图片大小怎么改?
  18. 拉线位移编码器零线有电的原因
  19. 两个PDF比较标出差异_如何快速比较两个PPT文档的差异,早学早知道!
  20. 两个同时comet matlab,matlab 三维绘制

热门文章

  1. 【优化算法】饥饿游戏搜索算法(HGS)【含Matlab源码 1802期】
  2. 【静脉检测】基于matlab手指静脉图像检测【含Matlab源码 1654期】
  3. 【运动学】基于matlab GUI模拟小球自由落体【含Matlab源码 1630期】
  4. 毕设题目:Matlab数字信号去噪
  5. 【人脸识别】基于matlab GUI肤色人脸识别定位【含Matlab源码 674期】
  6. 【情感识别】基于matlab支持向量机(SVM)语音情感识别【含Matlab源码 543期】
  7. 【裂缝识别】基于matlab组合BCOSFIRE过滤器墙体裂缝识别【含Matlab源码 321期】
  8. c语言程序设计怎么改卷,C语言程序设计(B卷)教程.doc
  9. ps软件电脑版_安装PS/AI/CDR软件,电脑配置的怎样?
  10. vue.js2.0 新手开发_vue.js2.0实战(1):搭建开发环境及构建项目