Spring 五:AOP
概要
AOP:Aspect oriented Programming 的缩写,意为:面向切面编程,通过预编译和运行期动态代理实现程序功能的统一维护的技术。主要包含有 Schema-based Aop,Spring Aop Api,AspectJ等。
主要功能:日志记录,性能统计,安全控制,事务处理,异常处理
实现方式:AspectJ(预编译实现),SpringAop,JbossAOp这两个是运行期动态代理。
相关术语:
切面(Aspect):一个关注点的模块化,这个关注点可能横切的多个对象。
连接点(JoinPoint):程序执行中某个特定的点。
通知(Advice):在切面的某个特定的连接点上执行的动作。
切入点(PointCut):匹配连接点的断言,在Aop中通知和切入点表达式的关联。
引入(Introduction):在不修改类代码的前提下,为类增加新的方法和属性。
目标对象(Target Object):被一个或多个切面通知的对象。
Aop代理(Aop proxy):Aop框架创建的对象,用来实现切面契约(Aspect contruct)
织入:把切面连接到其他的应用程序类型或对象上,并创建一个被通知的对象,分为:编译时织入,类加载时织入,执行时织入。
Advice:
前置通知:在某连接点之前执行的通知,但不能在连接点前执行。
返回后通知:在某连接点正常返回执行的通知。
抛出异常后通知:在方法抛出异常退出后执行的通知。
后通知:当某连接点退出的时候执行的通知。
环绕通知:包围一个连接点的通知。
Aop的用途:
1.提供声明式的企业服务,特别是EJB替代服务声明
2.允许用户定制自己的方面,以完成oop和Aop的互补应用。
实现原理
1.纯JAVA实现,不需要特殊的编译过程,不需要控制类的加载器层次。
2.目前只支持方法执行连接点。
3.不是为了提供最完整的Aop实现。而是侧重于提供一种Aop实现和Spring IOC容器之间的整合,用解决企业的各种问题。
4.Spring AOP不会与Aspect竞争,从而提供综合全面的AOP解决方案。
有接口和无接口的SpringAop实现区别。
1、SPring AOP默认使用的是JAVA SE动态代理,这使得任何接口都可以被代理。
2、Spring AOP中也可以使用CGLIB代理。
配置AOP的XML
Spring所有的切面和通知器都必须放在一个<aop:config>内部(可以配置包含多个<aop:config>元素),每个<aop:config>可以包含PointCut、Advisor、Aspect元素(但是他们必须按照这个顺序声明)
<aop:config> 风格的配置大量使用了Spring的自动代理机制
配置上在原始的Spring配置的基础上,添加AOP的命名空间
将配置文件的最后一句改为:http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
关于切入点的配置
PointCut常见的方式:
execution(public * *(..)) 表示执行切入点所有的public方法。
execution(* set*(..)) 表示切入点为执行所有set开始的方法。
execution(* cim.xyz.*(..)) 表示执行包cim类xyz下的所有方法。
execution(* cim..(..)) 表示执行包cim下的所有方法。
execution(* cim...(..)) 表示执行包cim下包含子包的所有方法。
within(com.xyz.service.*) within用于匹配指定类型的方法执行。但只能在AOP中使用。
Advice
前置通知<aop:before>的配置
配置格式<aop:before method="执行方法名称" pointcur-ref="切入点bean"/>
如下
再在Aspect和AspectBiz中添加before函数和biz函数。
public class AspectBiz {
public void biz() {
System.out.println("AspectBiz!");
}
}public class Aspect {
public void before() {
System.out.println("before.");
}
}
再在测试主函数中调用biz方法
输入出为
注意:
划线的部分的格式问题,格式不正确会导致异常。应该改为:
后置通知<aop:after-returning/>的配置
格式<aop:after-returning method="执行方法名称",pointcut-ref=""/>。操作方式和前置通知一样。如下。
输入为
抛出异常后扔出<aop:after-throwing/>
格式:<aop:after-throwing method="执行函数" pointcut-ref="切入点"/>
操作方式和上面一样。
为了能够测试出抛出异常后输出,我们在biz函数添加throw new RuntimeException();
final after配置:
格式是:<aop:after method="" pointcut-ref=""/>其他和上面一样。
Around advice
通知方法的第一个参数必须是ProceedingJoinPoint类型。如下
其他都是一样。
Introductions
简介允许一个切面声明一个实现指定接口的通知对象,并且提供了一个接口实现类来代表这些对象。
由<aop:aspect>中的<aop:declare-parents/>元素声明该元素用于声明所匹配的类型拥有一个新的parent(因此得名).
只支持singleton模式。
格式:<aop:declare-parents types-matching="指定的方法"
implement-interface="接口"
default-impl="接口的实现"/>