第三章 Spring的AOP
AOP的概念、AOP的基本原理和实现、Spring的AOP编程
一、AOP的概念
1、什么是AOP
AOP(Aspect-oriented programming,面向切面编程)。将应用程序中的交叉业务逻辑(事务、安全等等)提取出来,封装成切面。由AOP容器在适当的时机(编译或运行时),将这些切面动态织入到具体业务逻辑当中。
将程序当中交叉业务抽象成切面,然后动态的应用到具体业务逻辑代码之中。从而实现切面的复用,并且解耦了交叉业务逻辑代码与具体业务逻辑代码。
2、AOP编程的好处
1) 代码的耦合性降低了
2) 可以灵活的为代码提供了中间件服务。
二、AOP相关概念
1、Aspect(切面)
泛指交叉业务逻辑,对交叉业务逻辑的统称,是对交叉业务逻辑的抽象。 2、Advice(通知)
建议/通知,指具体的交叉业务逻辑,切面的具体实现。 3、Joinpoint(连接点)
连接点,是指切面代码可以被织入到目标对象的位置(属性、方法)。 4、Pointcut(切入点)
切入点,指切面具体应用的位置,具体可以插入到哪些类,哪些方法当中。通知应用到哪些类的哪些方法或属性之上的规则,更加具体。 5、Introduction(引入)
引入,指动态地给Bean类增加属性和方法的一种特殊的通知。 6、Target(目标对象)
目标对象,指切面应用到的对象。 7、Proxy(代理对象)
代理对象,指切面应用到目标对象之后形成的对象。 8、Weaving(织入)
织入,将切面代码插入到业务逻辑代码的过程。
(1) 编译时织入,要有特殊的编译器支持,如ASpectJ。 优点就是性能好,速度快。 (2) 在运行时,使用动态代理机制。
17
把切面代码插入目标对象中,形成动态代理机制。 实现简单点,但性能差些。
三、AOP基本原理
1、采用动态代理模式
动态代理:依据目标类、目标类的接口以及交叉业务代码(逻辑),自动生成代理对象。 java.lang.reflect.Proxy.newProxyInstance(
target.getClass().getClassLoader() //目标对象的加载器ClassLoader,
目标类实现的代理接口, 交叉业务代码处理类);
会根据传进来的三个参数,生成动态代理。
2、Spring AOP采用动态代理的过程:
1)Spring在默认情况(Bean类实现了业务接口<代理接口>)下,Spring使用动态代理机制实现AOP。
2)Bean类没有实现业务接口,Spring使用CGLib来生成代理对象,该代理对象是目标对象的子类,因为Bean类不是final类。
3)目标对象如果是final类,并且也没实现代理接口,就不能运用AOP。
四、Spring的通知(具体的业务逻辑)
1、Spring的通知类型
Advice是所有通知的父接口 1)MethodBeforeAdvice
类全名:org.springframework.aop.MethodBeforeAdvice (1)在方法调用之前,做处理。
(2)不能够改变目标方法的流程,也不能中断流程的处理过程(除非抛出异常) (3)不能够改变返回值 2)AfterReturningAdvice
类全名:org.springframework.aop.AfterReturningAdvice (1)在方法调用之后,做处理,做些简单的,不影响业务的操作。 (2)不能够改变返回值
(3)不能够改变目标方法的流程,也不能中断流程的处理过程(除非抛出异常) 3)MethodInterceptor
类全名:org.aopalliance.intercept.MethodInterceptor AOP联盟的接口,拦截器。
在目标方法调用之前以及之后,都做处理。 可以改变目标方法的返回值,也可以改变流程。 4)ThrowsAdvice
18
类全名:org.springframework.aop.ThrowsAdvice 在方法抛出异常后,做处理。
当该通知处理完异常后,会简单地将异常再次抛出给目标调用方法。
client ? server: proxy ? service ? ThrowsAdvice ? 最后将异常抛给了客户端。
2、配置过程:
(1)配置目标对象 (2)配置通知
(3)利用ProxyFactoryBean将通知织入到目标对象,形成一个动态代理对象 (4)客户端使用动态代理来访问目标对象的方法。
ProxyFactoryBean的作用:
依照配置信息,将切面应用到目标对象,生成动态代理对象。 (1) Spring只支持方法连接点,不支持属性连接点。
(原因是Spring AOP采用的是动态代理模式,而动态代理本身就是在方法调用前加入代码。)
(2) Spring只在运行时,将切面织入到目标对象。
(有些AOP实现,可以在编译是织入切面到目标对象。) Injecting Advice(con’t d) class=”org.springframework.aop.framework.ProxyFactoryBean”>
在默认情况下,通知会应用到所有的方法之上。
Pointcut:
根据方法和类决定在什么地方织入通知
Advisor:
19
将Pointcut与Advice结合到一起。
自定义切入点: 步骤:
1)实现org.springframework.aop.ClassFilter
2)实现org.springframework.aop.MethodMatcher 3)实现org.springframework.aop.Pointcut
4)实现org.springframework.aop.PointcutAdvisor 注意: 在此可定义
private Advice advice; private Pointcut pointcut;
在配置文件中,将自定义的切入点与通知绑订到一起 5)利用ProxyFactoryBean将advisor织入到目标对象
五、切入点(Pointcut)
1、pointcut
切入点是指通知/切面可以应用到哪些类,哪些方法之上。 Pointcut API
接口Pointcut:org.springframework.aop.Pointcut
对某些类某些方法应用切面。 private ClassFilter classFilter;
private MethodMatcher methodMatcher;
public set/get ClassFilter 和 public set/get MethodMatcher public ClassFilter getClassFilter(){ }
public MethodMatcher getMethodMatcher(){ }
接口Classfilter:org.springframework.aop.ClassFilter
用来过滤类(哪些类可以应用切面) Boolean matches( Class clazz); true:应用切面,false:不应用切面 public boolean matches( Class arg0 ){
String className = arg0.getSimpleName();
20

