【Spring系列】Spring AOP面向切面编程
前言
接上一篇文章,在上午中使用了切面做防重复控制,本文着重介绍切面AOP。
在开发中,有一些功能行为是通用的,比如、日志管理、安全和事务,它们有一个共同点就是分布于应用中的多处,这种功能被称为横切关注点(cross-cutting concerns)。
DI(依赖注入)有助于应用对象之间的解耦,而AOP可以实现横切关注点与他们所影响的对象之间的解耦。
面向切面编程在Spring AOP中有4种类型的调用,方法调用的之前、后、异常增加其他方法,方法调用的前和后调用其他方法,将方法中的参数传递给其他方法,讲一个崭新额的接口实现作为父类接口给其他方法所属的方法。我们在调用某个方法的时候,Spring AOP在其他勒种就为这个方法额外做了其他事情。
一、什么是面向切面编程?
继承和委托是最常见的实现通用功能的面向对象技术,切面提供了取代继承和委托的另一种选择,而且在很多场景下更清晰简洁。
在使用面向切面编程时,我们仍然在一个地方定义通用功能,但是我们可以提供声明的方式定义这个功能以何种方式在何处应用,而无需修改受影响的类,
横切关注点可以被模块化为特殊的类,这些类被称为切面。
二、切面术语:通知、连接点和切点、切面
切面是一个类,这个可的作用是完成对指定位置的指定动作的附属动作,指定位置首先有一个选择范围,可以是创建对象、方法调用、变量改变等等,这些选择范围就是连接点,你可以决定选取其中的一部分,这些被选中的部分就是切点,当然选择的过程在代码中实现,选好点后,一旦这些点被运行了,比如调用了一个类,切面里的类中的某个方法就会被调用,以完成别的功能,这个被调用的方法就是通知。
即:
- 切面:类
- 切点:切面关注的指定代码的动作连接点:可以作为切点的代码动作
- 通知:方法,切点处额外多出的方法
- 连接点:切点的代码动作
1、通知(Advice) 5种类型
切面的工作被称为通知
通知定义了切面的什么以及何时使用,除了描述切面要完成的工作,通知还解决了何时执行这个工作的问题。
根据应用于方法之前、后、前后、异常等可以分为
- Before:在方法调用前调用通知
- After:在方法被调用之后调用通知,无论方法是否执行成功
- After-returning:在方法成功执行之后调用通知
- After-throwing:在方法抛出异常后调用通知
- Around:方法被调用之前和调用之后个执行一次自定义的行为
2、连接点(Joinpoint)
连接点是在应用执行过程中能够插入切面的一个点,准确的说是程序运行中的某种时机,比如调用方法时,抛出异常时、甚至是修改一个字段时。切面代码可以利用这些点(时机)插入到应用的正常流程之中,并添加新的行为。
3、切点(Pointcut)
一个切面仅仅需要通知有限的连接点而不是全部的连接点,切点定义了连接点中的哪些是通知需要产生作用的,
切点会匹配通知所要织入的一个或者多个连接点
我们通常使用明确的类和方法名称来指定这些切点
简单的说,切点是相对于不同通知而言的有效连接点的集合
4、切面(Aspect)
切面是通知和切点的集合,通知决定做什么?何时?切点决定在那些地方进行通知。
5、引入(Introduction)
引入是一个过程的描述,指我们向现有的类添加新方法或属性。我们可以把一个类作为通知,引入到被通知的类中,从而在不改变被通知的类的情况下改变这个类。
6、织入(Weaving)
切面在指定的连接点(即通知在切点通知被通知的方法,通知被引入了被通知的类)被织入到目标对象中,括号中一直说被通知类增加了方法,这种增加的方法就是织入,说到底,织入是为被通知类创建了代理类,在代理类中增加了方法。从表面看来,被代理类增加了方法,即织入。
织入是将切面应用到目标对象来创建新的代理对象的过程。切面在指定的连接点被织入到目标对象中。
在目标对象的多个点可以进行织入。
通过在代理类中包裹切面,Spring在运行期将切面织入到Spring管理的Bean中。
编译期——切面在目标类编译时被织入。
·这种方式需要特殊的编译器。
·AspectJ的织入编译器就是以这种方式织入切面的。
类加载期——切面在目标类加载到JVM时被织入。
·这种方式需要特殊的类加载器(ClassLoader),它可以在目标类被引入应用之前增强该目标类的字节码。
·AspectJ 5的LTW(load-time weaving)就支持以这种方式织入切面。
运行期——切面在应用运行期间的某个时段被织入。
·一般情况下,在织入切面时,AOP容器会为目标对象动态地创建一个代理对象。
·Spring AOP 就是在运行期,为目标对象动态创建一个代理对象来实现织入的。当拦截到方法调用时。在调用目标Bean之前,代理会执行切面逻辑。直到应用需要被代理的Bean时,Spring才创建代理对象。
三、Spring对AOP的支持
1、Spring提供了4种各具特色的AOP支持
- 基于代理的经典AOP;
- @AspectJ注解驱动的切面;
- 纯POJO切面;
- 注入式AspectJ切面(适合Spring各版本)。
前3种都是Spring基于代理的AOP变体,因此,Spring对AOP的支持局限于方法拦截。如果AOP需求超过了简单方法拦截的范畴(如构造器或属性拦截),那么应该考虑在AspectJ里实现切面,利用Spring的DI(依赖注入)把Spring Bean注入到AspectJ切面中:
2、Spring只支持方法连接点
AspectJ和Jboss除了方法切点,还提供了字段和构造器接入点。所以,单单使用Spring我们无法构建细粒度的通知,也无法使用构造器连接点。对于这种情况,我们可以利用Aspect来协助Spring AOP。
3、切点规定了那些连接点
我们使用切点来选择连接点,然后是不同的通知匹配不同的切点。在Spring AOP中,需要使用AspectJ的切点表达式来定义切点。
4、Spring AOP所支持的AspectJ切点指示器
arg() 限制连接点匹配参数为指定类型的执行方法
@args() 限制连接点匹配参数由指定注解标注的执行方法
execution() 用于匹配是连接点的执行方法
this() 限制连接点匹配AOP代理的Bean引用为指定类型的类
target() 限制连接点匹配目标对象为指定类型的类
@target() 限制连接点匹配特定的执行对象,这些对象对应的类要具备指定类型的注解
within() 限制连接点匹配指定的类型
@within() 限制连接点匹配指定注解所标注的类型(当使用Spring AOP时,方法定义在由指定的注解所标注的类里)
@annotation 限制匹配带有指定注解连接点
只有execution切点指示器是唯一的执行匹配,而其他的切点指示器都是用于限制匹配的。
5、编写切点,这些最后被添加到xml配置文件中
注意:所写的路径都是接口类的路径,切点是在接口类中而不是具体的实现类中的。
不关注返回类型,不关注入参类型,在方法执行的时候引入切点
execution(* com.springination.springidol.Instrument.play(..))
增加限制-并且限定了切点的包路径(后者是多余的吗?)
execution(* com.springination.springidol.Instrument.play(..))
and within(com.springinaction.springidol.*)
在spring2.5之后,可以通过id来限定bean
execution(* com.springination.springidol.Instrument.play(..))
and within(com.springinaction.springidol.*)
and bean(eddie)
当然也可以使用反向操作
execution(* com.springination.springidol.Instrument.play(..))
and within(com.springinaction.springidol.*)
and bean(eddie)
and !bean(eddie2)
6、在XML中声明切面
AOP配置元素 描述
<aop:advisor> 定义AOP通知器
<aop:after> 定义AOP后置通知(不管被通知的方法是否执行成功)
<aop:after-returning> 定义AOP after-returning通知
<aop:after-throwing> 定义after-throwing通知
<aop:around> 定义AOP环绕通知
<aop:aspect> 定义切面
<aop:aspect-autoproxy> 启用@AspectJ注解驱动的切面
<aop:before> 定义AOP前置通知
<aop:config> 顶层的AOP配置元素。大多数的<AOP:*>元素,必须包含在 <aop:config>元素内
<aop:declare-parents> 为被通知的对象引入额外的接口,并透明地实现
<aop:pointcut> 定义切点
【Spring系列】Spring AOP面向切面编程的更多相关文章
- Spring Boot2(六):使用Spring Boot整合AOP面向切面编程
一.前言 众所周知,spring最核心的两个功能是aop和ioc,即面向切面和控制反转.本文会讲一讲SpringBoot如何使用AOP实现面向切面的过程原理. 二.何为aop aop全称Aspec ...
- Spring(3):AOP面向切面编程
一,AOP介绍 AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开 ...
- Spring Boot之AOP面向切面编程-实战篇
目录 前言 编程范式主要有以下几类 引入pom依赖 aop注解 实现日志分割功能 前言 AOP是一种与语言无关的程序思想.编程范式.项目业务逻辑中,将通用的模块以水平切割的方式进行分离统一处理,常用于 ...
- 【Spring 核心】AOP 面向切面编程
一.什么是面向切面编程? 二.通过切点来选择连接点 三.使用注解创建切面 四.在XML中声明切面 五.注入AspectJ切面
- Spring注解式AOP面向切面编程.
1.AOP指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式.aop底层是动态代理. package com.bie.config; import org.aspectj.lan ...
- Spring:AOP面向切面编程
AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果. AOP是软件开发思想阶段性的产物,我们比较熟悉面向过程O ...
- 详细解读 Spring AOP 面向切面编程(二)
本文是<详细解读 Spring AOP 面向切面编程(一)>的续集. 在上篇中,我们从写死代码,到使用代理:从编程式 Spring AOP 到声明式 Spring AOP.一切都朝着简单实 ...
- 浅谈Spring AOP 面向切面编程 最通俗易懂的画图理解AOP、AOP通知执行顺序~
简介 我们都知道,Spring 框架作为后端主流框架之一,最有特点的三部分就是IOC控制反转.依赖注入.以及AOP切面.当然AOP作为一个Spring 的重要组成模块,当然IOC是不依赖于Spring ...
- Spring 08: AOP面向切面编程 + 手写AOP框架
核心解读 AOP:Aspect Oriented Programming,面向切面编程 核心1:将公共的,通用的,重复的代码单独开发,在需要时反织回去 核心2:面向接口编程,即设置接口类型的变量,传入 ...
- 基于SpringBoot AOP面向切面编程实现Redis分布式锁
基于SpringBoot AOP面向切面编程实现Redis分布式锁 基于SpringBoot AOP面向切面编程实现Redis分布式锁 基于SpringBoot AOP面向切面编程实现Redis分布式 ...
随机推荐
- CloudSetuper
地址:http://setup.qframer.com/help CloudSetuper CloudSetuper 是一款windows上的安装包制作工具,类似 NSIS or Inno Setup ...
- R 语言 相关入门资料
<R语言基础语法入门>: http://www.xueqing.tv/upload/april-training/day1/index.html#1
- laravel-第一課安裝
本地安装laravel,php环境要配置好,推荐xmapp一键搭建. 1.程序包直接从官方下载,官方开源地址:https://github.com/laravel/laravel(当然也可从此网站:h ...
- [译]Intel App Framework 3.0的变化
App Framework 3.0 原文 IAN M. (Intel) 发布于 2015-02-11 05:24 我们高兴地宣布App Framework 的新版本3.0发布了.你可以获得最新的代码 ...
- YFCMF 问题
1.菜单不见了,yf.php (main 改为0 ) function tagMenu $parseStr .='echo get_menu("main","'.$to ...
- Backlight当前行背景高亮显示
下载地址:https://github.com/limejelly/Backlight-for-XCode PS:Xcode 8.0 默认支持了 跟VVDocumenter规范注释生成器的安装方式一样 ...
- python的redis简单使用
安装的Python版本 3.6.1 redis安装的2.8 安装redis模块 pip install redis 简单使用 redis-test.py import redis r=redis.Re ...
- 【QT】error: Failed to retrieve MSVC Environment from "\VC\vcvarsall.bat":
安装QT后直接打开,报错. 需要删mysql环境变量. error: Failed to retrieve MSVC Environment from "D:\Englishpath\VS2 ...
- SDK Manager.exe和AVD Manager.exe缺失,Android SDK Tools在检查java环境时卡住了,未响应卡死!
之前安装Android Studio的时候根据提示安装了Android SDK,但是发现目录下没有SDK Manager.exe和AVD Manager.exe,导致SDK的一些操作很不方便! 不知道 ...
- mysql中删除binlog的方法?mysql中如何删除binlog?
需求描述: 在mysql中如何删除binlog,因为随着数据库的运行,mysql中产生的binlog会越来越大,有可能把磁盘撑爆了,所以记录下删除 binlog的方法. 操作过程: 1.通过系统参数控 ...