AOP(Aspect-Oriented  Programming,面向切面编程)是Spring提供的关键技术之一。

AOP基于IoC,是对OOP(Object-Oriented Programming,面向对象编程)的有效补充。

利用一种“横切”的技术,剖解封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为Aspect(切面,也称方面)。

AOP的核心思想就是“将应用程序中的业务逻辑与对其提供支持的通用服务功能进行分离,而业务逻辑与通用服务功能之间通过配置信息,实现整合”。

实现AOP的技术主要分为两大类:

一是采用动态代理技术,采用拦截器截取消息的方法,对该消息进行“插装”,以取代原有对象行为的执行;

二是采用静态织入的方式,引入特定的语法创建“切面”,从而使得编译器可以在编译期间织入有关“切面”代码。

Spring AOP是实现AOP的一种技术,是采用“动态代理技术”实现的。

(一)AOP技术相关的概念和术语

1)几个相关概念:

在小编的上篇博文中,在对原来的业务逻辑进行处理加入AOP部分时,类A中所有方法的执行前后,都成为了“所关注的地方”,这个地方称为“横切关注点”。这样原来的业务逻辑被分割开来,所以这个点也就成了联系前后逻辑的连接点,称为“连接点”。然后,对于整个原来的业务逻辑,我们需要告诉程序“在什么时候添加新的附加功能”,这里的“什么时候”的时机称为“通知”。在本例中“通知”有两个:“在类A中所有方法的执行前添加”称为“前置通知”;“类A中所有方法的执行后添加”称为“后置通知”。

例子中前置通知:

<!-- 配置前置通知及前置通知的切入点 -->
<aop:before method="methodX1" pointcut="execution(* com.edu.aop.hello.A.*())"></aop:before>

后置通知:

<!-- 配置后置通知及后置通知的切入点 -->
<aop:after method="methodX2" pointcut="execution(* com.edu.aop.hello.A.*())"></aop:after>

当原来的业务逻辑被“横向关注点”分割后,就可以在“该点”处插入(切入)新需求功能模块,这里将指明插入(切入)新需求功能模块的“地方”(配置文件代码部分)称为“切入点(Pointcut)”,而要插入的功能模块,称为“切面(Aspect)”。可见,配置“切面”就是指出:在什么地方(连接点)切入什么模块(切面)的哪个方法

2)Aspect(切面,也称方面)

是对系统中横切关注点逻辑进行模块化封装的AOP概念实体(就是定义一个类),它可以包含多个Pointcut(切入点)及相关的Advice(通知)定义。例如本例中的类X。

3)JoinPoint(连接点)

系统在运行之前,AOP的功能模块需要织入到OOP的功能模块中。要进行这种织入过程,需要知道在系统的哪些功能点上进行织入操作,这些将要在其上进行织入操作的系统功能点称为JoinPoint。

在Spring AOP中,一个连接点总是表示一个方法的执行。

常见的几种JoinPoint类型:方法调用、方法执行、构造方法调用、构造方法执行、字段设置、字段获取、异常处理执行、类初始化。

4)Pointcut(切入点)

Pointcut是对JoinPoint的形式描述,用于指出要对哪些Joinpoint进行拦截的定义。

(初学可理解为二者相同,只不过Pointcut用在配置文件的通知中;JoinPoint用在切面类中)

Pointcut通常和“一个切入点表达式”相关联,来表示在需要在哪些功能点上织入AOP的功能。

常见的Pointcut方式:

(1)直接指定JoinPoint所在的方法名称;

(2)正则表达式,Spring的AOP支持该种方式;

(3)使用特定的Pointcut表述语言。

5)Advice(通知)

一个Advice对应一个横切关注点逻辑的载体,它代表将会织入到JointPoint的横切逻辑:在切面的某个特定的连接点上执行的逻辑。

一个切面包括一个或者多个通知,每个通知就是告诉“在什么时机”调用执行什么方法。

Spring AOP提供了5种通知:

Before Advice(前置通知)、After Returning Advice(返回通知)、After throwing Advice(异常通知)、After Advice(后置通知)、Around Advice(环绕通知)

6)Target(目标对象)

通知被应用的对象(包含连接点的对象,或者说被通知或被代理的对象),即符合Pointcut所指定的条件,将在织入过程中被织入横切逻辑的对象。

本例中,即是A类的所有方法。

7)AOP Proxy(AOP 代理)

AOP框架创建的对象,用来执行切面(Aspect)的内容。

8)Weave(织入)

将Aspect应用到Target对象并导致Proxy对象创建的过程称为织入。

9)拦截机(Interceptor)

拦截器(也称拦截机)是AOP的另一种叫法。

(二)切入点表达式

通常,切入点表达式用于给出Pointcut对JointPoint的形式描述,指出要对哪些JoinPoint进行拦截。

切入点表达式的格式如下:

execution(方法访问权限 返回类型 方法的包路径.方法名(方法的参数)异常类型)

例如本例中:

execution(* com.edu.aop.hello.A.*())

使用说明:

1)“返回类型”、“方法名”和“方法参数”是必选项,其他各项是可选项;

2)在“切入点表达式”中可以使用通配符。

常用通配符:

“*”代表不包含“.”的字符串,若要包含“.”,必须使用转义符号“\.”;

“..”代表任意数量任意类型的参数。

3)名称模式匹配的是方法名。可以用*通配符表示匹配所有方法名。

4)若在同一包中,可省略包名,直接给出类(接口)名称;

5)切入点表达式可以通过操作符“&&”、“||”、“!”进行合并运算,形成一个新的切入点表达式。

例:

execution(* com.edu.aop.hello.A.*())||execution(* *.add(..))

(三)两种常用的AOP编程方法

1)基于XML配置的AOP编程。上篇博文案例就是此种编程方法,重点就是配置“切面信息”;

2)基于AspectJ注解配置的AOP编程。采用注解方式编程,所有的配置信息都在源代码中标注,非常简单方便。

两种AOP编程方法的设计思想与设计过程基本一致,即创建切面类、配置(注解)切面和配置(注解通知)。

参考书籍:《Java EE框架开发技术与案例教程》

Spring学习之旅(六)Spring AOP工作原理初探的更多相关文章

  1. Spring学习之旅(六)--SpringMVC集成

    对大多数 Java 开发来说,基于 web 的应用程序是我们主要的关注点. Spring 也提供了对于 web 的支持,基于 MVC 模式的 Spring MVC 能够帮助我们灵活和松耦合的完成 we ...

  2. Spring 学习笔记(六)—— AOP的简单理解

    系统中的业务可以分为核心关注点和横切关注点. 核心关注点时业务处理的主要流程,而横切关注点是与核心业务无关但更为通用的业务. 各个横切关注点离散地穿插于核心业务之中,导致系统地每一个模块都与这些业务具 ...

  3. Spring学习之旅(八)Spring 基于AspectJ注解配置的AOP编程工作原理初探

    由小编的上篇博文可以一窥基于AspectJ注解配置的AOP编程实现. 本文一下未贴出的相关代码示例请关注小编的上篇博文<Spring学习之旅(七)基于XML配置与基于AspectJ注解配置的AO ...

  4. Spring学习(二)——Spring中的AOP的初步理解[转]

      [前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring. ...

  5. Spring学习(二)——Spring中的AOP的初步理解

    [前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring.不知 ...

  6. spring 学习(三):aop 学习

    spring 学习(三):aop 学习 aop 概念 1 aop:面向切面(方面)编程,扩展功能不修改源代码实现 2 AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码 3 aop底层使用动态代 ...

  7. Spring学习之旅(十)--MockMvc

    在之前的 Spring学习之旅(八)--SpringMVC请求参数 我们是通过在控制台输出来验证参数是否正确,但是这样做实在是太耗时间了,我们今天来学习下 MockMvc,它可以让我们不需要启动项目就 ...

  8. Spring学习之——手写Spring源码V2.0(实现IOC、D、MVC、AOP)

    前言 在上一篇<Spring学习之——手写Spring源码(V1.0)>中,我实现了一个Mini版本的Spring框架,在这几天,博主又看了不少关于Spring源码解析的视频,受益匪浅,也 ...

  9. Spring学习(三)——Spring中的依赖注入的方式

    [前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring.不知 ...

随机推荐

  1. C#8个常用的字符串的操作

    1.根据单个分隔字符用split截取 string st="GT123_1"; string[] sArray=st.split('_'); 输出:sArray[0]=" ...

  2. springboot2.0jar包启动异常

    今天碰到一个异常: 08:44:07.214 [main] ERROR org.springframework.boot.SpringApplication - Application run fai ...

  3. Python开发之---PyCharm初体验

    PyCharm 的初始设置(知道) 目标 恢复 PyCharm 的初始设置 第一次启动 PyCharm 新建一个 Python 项目 设置 PyCharm 的字体显示 PyCharm 的升级以及其他 ...

  4. NIO/BIO

    NIO/BIO    BIO网络通信        概述            网络编程的基本模型是Client/Server模型,也就是两个进程之间进行相互通信,其中服务端提供位置信息(绑定的IP地 ...

  5. 小程序第三方框架对比 ( wepy / mpvue / taro )

      众所周知如今市面上端的形态多种多样,手机Web.ReactNative.微信小程序, 支付宝小程序, 快应用等,每一端都是巨大的流量入口,当业务要求同时在不同的端都要求有所表现的时候,针对不同的端 ...

  6. 浅谈工作单元 在整个 ABP 框架当中的应用

    ABP在其内部实现了工作单元模式,统一地进行事务与连接管理. 其核心就是通过 Castle 的 Dynamic Proxy 进行动态代理,在组件注册的时候进行拦截器注入,拦截到实现了 Unit Of ...

  7. Java核心技术及面试指南 异常部分的面试题归纳以及答案

    4.2.4.1 throw和throws有什么差别?异常(Exception)和错误(Error)有什么差别? throw语句表示抛出异常,由方法体内的语句处理.throws语句用在方法声明后面,表示 ...

  8. 解决java.lang.IllegalArgumentException: No converter found for return value of type: class java.util.ArrayList的问题

    一.背景 最近闲来无事,想自己搭建一套Spring+SpringMVC+Mybatis+Mysql的环境(搭建步骤会在以后博客中给出),结果运行程序时,适用@ResponseBody注解进行返回Lis ...

  9. 支付宝PC端单笔支付同步回调session失效问题

    一次调用支付宝PC场景下单笔支付之后同步回调遇到的session失效问题记录 问题描述: 调用支付宝接口:alipay.trade.page.pay,该接口请求参数中有两个返回地址需要设置,retur ...

  10. 【EF6学习笔记】(十一)实施继承

    上篇链接:EF学习笔记(十) 处理并发 本篇原文链接:Implementing Inheritance 面向对象的世界里,继承可以很好的重用代码.在本章就对Instructor和Student两个类进 ...