您的位置:首页 > 编程语言 > Java开发

Spring 3 AOP 概念介绍

2017-08-10 15:07 393 查看
AOP概念
AOP(Aspect Oriented Programming),即面向切面编程(也叫面向方面编程,面向方法编程)。其主要作用是,在不修改源代码的情况下给某个或者一组操作添加额外的功能。像日志记录,事务处理,权限控制等功能,都可以用AOP来“优雅”地实现,使这些额外功能和真正的业务逻辑分离开来,软件的结构将更加清晰。AOP是OOP的一个强有力的补充。
AOP术语
AOP的术语不太直观,Spring文档中也没有给一个确切的定义,所以重在理解。
Join Point: Spring AOP中,join point就是一个方法。(通俗来讲就是起作用的那个方法)。
Pointcut: 用来指定join point(通俗来讲就是描述的一组符合某个条件的join point)。通常使用pointcut表达式来限定joint point,Spring默认使用AspectJ pointcut expression language。
Advice: 在join point上特定的时刻执行的操作,Advice有几种不同类型,下文将会讨论(通俗地来讲就是起作用的内容和时间点)。
Introduction:给对象增加方法或者属性。
Target object: Advice起作用的那个对象。
AOP proxy: 为实现AOP所生成的代理。在Spring中有两种方式生成代理:JDK代理和CGLIB代理。
Aspect: 组合了Pointcut与Advice,在Spring中有时候也称为Advisor。某些资料说Advisor是一种特殊的Aspect,其区别是Advisor只能包含一对pointcut和advice,但是aspect可以包含多对。AOP中的aspect可以类比于OOP中的class。
Weaving:将Advice织入join point的这个过程。
Advice的类型
Before advice:  执行在join point之前的advice,但是它不能阻止joint point的执行流程,除非抛出了一个异常(exception)。
After returning advice: 执行在join point这个方法返回之后的advice。
After throwing advice: 执行在join point抛出异常之后的advice。
After(finally) advice: 执行在join point返回之后或者抛出异常之后的advice,通常用来释放所使用的资源。
Around advice: 执行在join point这个方法执行之前与之后的advice。
实现机制
Spring AOP是基于代理机制的,通过JDK Proxy和CGLIB Proxy两种方法实现代理。
如果target object没有实现任何接口,那么Spring将使用CGLIB来实现代理。CGLIB是一个开源项目,它是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。
如果target object实现了一个以上的接口,那么Spring将使用JDK Proxy来实现代理,因为Spring默认使用的就是JDK Proxy,并且JDK Proxy是基于接口的。这也是Spring提倡的面向接口编程。当然,你也可以强制使用CGLIB来进行代理,但是这样可能会造成性能上的下降。
Pointcut expression
Pointcut可以有下列方式来定义或者通过&& || 和!的方式进行组合. 
args()
@args()
execution()
this()
target()
@target()
within()
@within()
@annotation
其中execution 是用的最多的,其格式为:
ret-type-pattern,name pattern, 和 parameters pattern是必须的.
ret-type-pattern:可以为*表示任何返回值,全路径的类名等.
name-pattern:指定方法名,*代表所以,set*,代表以set开头的所有方法.
parameters pattern:指定方法参数(声明的类型),(..)代表所有参数,(*)代表一个参数,(*,String)代表第一个参数为任何值,第二个为String类型.
举例说明:
1) 任意公共方法的执行:
execution(public * *(..))
2) 任何一个以“set”开始的方法的执行:
execution(* set*(..))
3) AccountService 接口的任意方法的执行:
execution(* com.xyz.service.AccountService.*(..))
4) 定义在service包里的任意方法的执行:
execution(* com.xyz.service.*.*(..))
5) 定义在service包和所有子包里的任意类的任意方法的执行:
execution(* com.xyz.service..*.*(..))
6) 定义在pointcutexp包和所有子包里的JoinPointObjP2类的任意方法的执行:
execution(* com.test.spring.aop.pointcutexp..JoinPointObjP2.*(..))
7) pointcutexp包里的任意类.
within(com.test.spring.aop.pointcutexp.*)
8) pointcutexp包和所有子包里的任意类.
within(com.test.spring.aop.pointcutexp..*)
9) 实现了Intf接口的所有类,如果Intf不是接口,限定Intf单个类.
this(com.test.spring.aop.pointcutexp.Intf)
10) 带有@Transactional标注的所有类的任意方法.
@within(org.springframework.transaction.annotation.Transactional)
@target(org.springframework.transaction.annotation.Transactional)
11) 带有@Transactional标注的任意方法.
@annotation(org.springframework.transaction.annotation.Transactional)
12) 参数带有@Transactional标注的方法.
@args(org.springframework.transaction.annotation.Transactional)
13) 参数为String类型(运行是决定)的方法.
args(String)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: