(五)Spring 中的 aop
目录
AOP概念
浅理解
aop
:面向切面编程,扩展功能不需要修改程序源代码 ;深度理解
aop
:采取了横向抽取机制
,取代了传统纵向继承体系
复杂性代码 ;概念看完,不一定懂,aop 到底是怎么完成不修改源代码,,而进行功能扩展的 ; 往下看 原理 ;
AOP原理
传统的
纵向继承体系
想要对功能进行扩展,最原始的做法是:修改源代码,在源代码上直接添加功能代码;但是,这样做,会产生了一个
问题
:假如有几个方法,都要增加一个相同的功能,就务必会有重复性代码的产生;后来有人想到了
纵向继承体系
,就像图中的那样,要增强功能的时候,写一个基类,然后让要扩展的类,继承基类,达到扩展功能的目的 ;这样解决了重复代码的问题,但是还有问题,就是扩展类和基类绑定在一起了,耦合高,只要基类方法改名字,要扩展的类,就得相应的改名字 ;aop
的横向抽取一(有接口
JDK动态代理
)Spring
的aop
底层是使用动态代理
实现的 ;动态代理
分为2中,有接口、无接口 ;aop
的横向抽取二(没有接口
cglib
)动态代理
怎么操作的,这里不讲,这里主要表达aop
底层是动态代理
;
AOP术语
Joinpoint(连接点)
官方解释
:就是那些被拦截到的点,在Spring
中这些点就是方法
,因为 spring 只支持方法类型的连接点 ;大白话
:就是类里面,可以 被增强的方法 ;Pointcut
(切入点)官方解释
:对连接点进行拦截的定义 ;大白话
:类中 实际 被增强的方法 ;Advice
(通知、增强)官方解释
:拦截到连接点以后,要做的事;通知分为:前置通知、后置通知、异常通知、最终通知、环绕通
重点内容`(切面要完成的功能)大白话
:实际要扩展的功能 ;前置通知
:在原方法执行之前,进行功能的扩展 ;
后置通知
:在原方法执行之后,进行功能的扩展 ;
异常通知
:在方法出现异常的还是,进行功能的扩展 ;
最终通知
:在后置通知
之后,进行功能的扩展 ;
环绕通知
:在方法之前和之后,都进行功能的扩展 ;Introduction(引介)
是一种特殊的通知,在不修改类代码的前提下,Introduction 可以在运行期为类动态的添加一些方法或者字段 ;
Target(目标对象)
代理的目标对象,即要增强的类 ;
Weaving(植入)
把要增强应用到目标的过程 ;
Proxy(代理)
一个类被 AOP 植入增强以后,就会产生一个代理类 ;
Aspect(切面)
官方解释
:切入点和通知(引介)的结合;大白话
:把扩展的功能,应用到要增强的方法上的过程 ;
Spring
中的 aop
的操作
AspectJ
框架
Aspect
是一个面向切面的框架(不是Spring
里面的,是一个独立的框架,可以和Spring
搭配使用),它扩展了java
语言。AspectJ
定义了AOP
语法,所以它有一个专门的编译器
用来生成遵守java
字节编码规范的Class
文件 ;AspectJ
是一个基于java
语言的AOP
框架;Spring2.0
以后新增了对AspectJ
切点表达式支持;@AspectJ
是AspectJ 1.5
新增功能,通过JDK
注解技术,允许直接在Bean
类中定义切面 ;- 新版本
Spring
框架,建议使用AspectJ
方式来开发AOP
; - 使用
AspectJ
需要导入Spring aop
和AspectJ
相关的jar
包 ;
使用 AspectJ
实现 aop
的两种方式
基于
AspectJ
的配置方式导包
除了
Spring-aop
的包,还需要AspectJ
的aopalliance-1.0、aspectjweaver-1.8.11
两个包 ;配置文件添加新的约束
添加 aop 的相关约束
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation=
"http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"
使用表达式配置切入点
常用表达式:
execution(<访问修饰符>?<返回类型><方法名>(参数)<异常>
例如:
写法:
execution
(*
+空格
+方法名全路径
)
// 匹配 包路径xin.ijava.aop 下面的 Book 类的 add()方法 // * 表示任意都匹配 写在这里匹配保护:public、private、abstract
// add(..) 表示匹配由于参数都行
execution(* xin.ijava.aop.Book.add(..)) -------------------------------------
// 匹配 包路径xin.ijava.aop 下面的 Book 类的 所有方法
execution(* xin.ijava.aop.Book.*(..)) -------------------------------------
// 匹配 包路径xin.ijava.aop 下面的所有方法(不包含子包)
execution(* xin.ijava.aop.*(..)) -------------------------------------
// 匹配 包路径xin.ijava.aop 下面的所有方法(包含子包)
execution(* xin.ijava.aop..*(..)) -------------------------------------
// 匹配 任意包路径下面的任意类的任意方法
execution(* *.*(..)) -------------------------------------
// 匹配 所有以 add 开头的方法
execution(* add*(..)) -------------------------------------
// 匹配 实现特定接口(xin.ijava.aop.dao)的所有类方法
execution(* xin.ijava.aop.dao+*(..))在配置文件中配置切入点
<aop:config>
<!--配置切入点-->
<aop:pointcut id="bookPointCut" expression="execution(* ijava.xin.aop.Book.*(..))"/> <!--配置切面-->
<!--ref 中是 增强对象,不是要增强的对象-->
<aop:aspect ref="bookAdvice">
<!--前置通知-->
<aop:before method="beforeAdd" pointcut-ref="bookPointCut"></aop:before>
</aop:aspect> </aop:config>
环绕通知
环绕通知和其他通知,有点不一样
增强对象中,
环绕通知方法
的代码:/**
* 环绕通知
* @param proceedingJoinPoint 参数
*/
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("前置通知.."); // 调用增强的方法
proceedingJoinPoint.proceed() ; System.out.println("后置通知.."); }
基于
AspectJ
的注解方式在
Spring 配置文件
中开启AOP
自动代理<!--开启aop自动代理-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
然后在
增强类
上面写一个@Aspect
注解 ;在要
增强类
的增强方法上写注解,配置切入点
@Component("bookAdvice")
@Aspect
public class BookAdvice { @Before(value = "execution(* ijava.xin.aop.Book.*(..))")
public void beforeAdd(){
System.out.println("前置通知..");
}
/**
* 环绕通知
* @param proceedingJoinPoint 参数
*/
@Around(value = "execution(* *.*(..))")
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("前置通知1.."); // 调用增强的方法
proceedingJoinPoint.proceed() ; System.out.println("后置通知1.."); }
}
border="0" src="//music.163.com/outchain/player?type=2&id=1297001123&auto=1&height=66" width="1" height="0">
(五)Spring 中的 aop的更多相关文章
- Spring中的AOP 专题
Caused by: java.lang.IllegalArgumentException: ProceedingJoinPoint is only supported for around advi ...
- Spring学习笔记(四)—— Spring中的AOP
一.AOP概述 AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善.O ...
- 2018.12.24 Spring中的aop演示(也就是运用aop技术实现代理模式)
Aop的最大意义是:在不改变原来代码的前提下,也不对源代码做任何协议接口要求.而实现了类似插件的方式,来修改源代码,给源代码插入新的执行代码. 1.spring中的aop演示 aop:面向方面编程.不 ...
- JavaWeb_(Spring框架)认识Spring中的aop
1.aop思想介绍(面向切面编程):将纵向重复代码,横向抽取解决,简称:横切 2.Spring中的aop:无需我们自己写动态代理的代码,spring可以将容器中管理对象生成动态代理对象,前提是我们对他 ...
- Spring 中基于 AOP 的 @AspectJ
Spring 中基于 AOP 的 @AspectJ @AspectJ 作为通过 Java 5 注释注释的普通的 Java 类,它指的是声明 aspects 的一种风格. 通过在你的基于架构的 XML ...
- Spring 中基于 AOP 的 XML架构
Spring 中基于 AOP 的 XML架构 为了使用 aop 命名空间标签,你需要导入 spring-aop j架构,如下所述: <?xml version="1.0" e ...
- Spring中的AOP
什么是AOP? (以下内容来自百度百科) 面向切面编程(也叫面向方面编程):Aspect Oriented Programming(AOP),通过预编译方式和运行期动态代理实现程序功能的统一维护的一种 ...
- Spring中关于AOP的实践之概念
一.什么是AOP AOP:也称作面向切面编程 在分享几个概念执行我想先举个栗子(可能例子举得并不是特别恰当): 1.假如路人A走在大街上,被一群坏人绑架了: 2.警察叔叔接到报警迅速展开行动:收集情报 ...
- spring中的AOP 以及各种通知 配置
理解了前面动态代理对象的原理之后,其实还是有很多不足之处,因为如果在项目中有20多个类,每个类有100多个方法都需要判断是不是要开事务,那么方法调用那里会相当麻烦. spring中的AOP很好地解决了 ...
随机推荐
- Luogu5298 [PKUWC2018]Minimax
太久没写博客了,过来水一发. 题目链接:洛谷 首先我们想到,考虑每个叶节点的权值为根节点权值的概率.首先要将叶节点权值离散化. 假设现在是$x$节点,令$f_i,g_i$分别表示左/右节点的权值$=i ...
- python 识别鼠标左键点击
#coding=utf- import pyHook import pythoncom # 监听到鼠标事件调用 def onMouseEvent(event): if(event.MessageNam ...
- loadrunner11安装
今天虚拟机里面装了下lr11,虚拟机版本是vm9.0,先在虚拟机里面装了windows2003,当然lr也是可以装在自己电脑上面的,但是最好是纯净的环境,由于我电脑东西比较多,所以我就装在虚拟机里面了 ...
- RuntimeException异常处理汇总
Java中所有异常的父类是Throwable类,在Throwable类下有两大子类: 一个是Error类,指系统错误异常,例如:VirtualMachineError 虚拟机错误,ThreadDeat ...
- oracle查询历史执行语句
SELECT * FROM v$sqlarea WHERE PARSING_SCHEMA_NAME='GAVIN' and SQL_TEXT LIKE '%delete%' ORDER BY LAST ...
- vi下如何配置自动更新标签(tags)?
答: 在~/.vimrc中写入以下内容即可: au BufWritePost *.c,*.cpp,*.h silent! !ctags -R & 参考资料: 一键打造vim ide
- 阶段5 3.微服务项目【学成在线】_day02 CMS前端开发_03-vuejs研究-vuejs基础-入门程序
本次测试我们在门户目录中创建一个html页面进行测试,正式的页面管理前端程序会单独创建工程. 在门户目录中创建vuetest目录,并且在目录下创建vue_01.html文件 <!DOCTYPE ...
- thinkphp5 更改入口文件在主目录
默认thinkPHP入口文件在public/index.php,而在虚拟主机部署时,不能设置访问路径,因此需要将入口文件放置在主目录上. 一.主目录下新建index.php 复制以下内容 // 定义应 ...
- delphi 根据数据库结构生成TreeView
procedure TUIOperate.FillTree(treeview: TTreeView); var findq: TADOQuery; node: TTreeNode; / ...
- 关于运维之故障复盘篇-Case Study
关于故障的事后复盘,英文名 Case Study是非常有必要做的,当然是根据故障的级别,不可能做到每个故障都Case Study,除非人员和时间充足: 文档能力也是能力的一种,一般工程师的文档能力比较 ...