Spring AOP 笔记

精通 Spring4.x 企业级应用》学习笔记

Aop 适合具有横切逻辑的应用场合:性能监测、访问控制、事务管理、日志记录;

Aop 通过横向抽取机制为这类无法通过纵向继承体系进行抽象的重复性代码提供了解决方案。

Aop 术语:

1.Joinpoint连接点:程序执行的某个特定位置,两个信息确定连接点:程序执行点和相对位置,spring 使用切点对执行点进行定位,而方位则在增强类型中定义。

2.Poincut切点:连接点是程序中客观存在的事物,Aop 通过切点定位特定的 接连点,切点通过类和方法作为连接点的查询条件。

3.Advice增强:增强包含连接点的方位信息和一段程序代码。通过切点信息和方位信息就可以找到特定的连接。

4.Target目标对象:织入目标类。

5.Introduction引介:特殊的增强,为类添加一些属性和方法。可以动态的为业务添加接口的实现逻辑,让业务类成为这个接口的实现类。

6.Weaving织入:织入是将增强添加到目标类具体连接点上的过程。
(1)编译期织入
(2)类装载期织入
(3)动态代理织入
spring 采用动态代理织入,AspectJ 采用编译期织入和类装载期织入

7.Proxy代理:类被织入增强后就产生一个结果类,它是融合原类和增强逻辑的代理类。可能是和原类具有相同接口的类也可能就是原类的子类。可以采用调用原类的方式调用代理类。

8.Aspect切面:切点和增强组成。

Aop 工作重心:

1.通过切点和增强定位到连接点
2.在增强中编写切面的代码

Spring AOP:

Spring AOP 使用动态代理技术在运行期间织入增强的代码,Spring AOP 使用两种代理机制:基于 JDK 的动态代理、基于 CGLib 的动态代理。

JDK 动态代理:

涉及两个类:java.lang.reflect.Proxy 和 java.lang.reflect.InvocationHandler;通过一个 InvocationHandler接口实现类 PerformanceHander,实现横切逻辑代码,然后通过 Proxy 结合 PerformanceHander 通过反射获得目标类实例创建代理实例。这样就可以像调用目标接口的实例相同的方式调用代理实例。从而实现横切逻辑代码的抽取。

CGLib 动态代理:

JDK 动态代理只能为接口创建代理实例。CGLib 通过底层的字节码技术为一个类创建子类,在子类中拦截所有父类的方法调用并顺势织入横切逻辑。因为 CGLib 采用的是动态创建子类的方式生成代理对象,多以不能对目标类中的 final 和 private 方法进行代理。

Spring AOP 小结:

通过 PerformanceHandler 或 CglibProxy 实现横切逻辑的动态织入存在三个问题:(1)目标类所有方法都添加了横切逻辑(2)通过硬编码的方式指定了织入点即方法开始和结束前(3)创建代理的过程无法做到通用。

Spring AOP 通过切面(Advisor)将 Pointcut 和 Advice 组装起来,利用 JDK 或 CGLib 统一的为目标 Bean 创建代理对象。
对于 singleton 代理对象或具有实例池的代理比较适合 CGLib 动态代理技术,反之适合 JDK 动态代理技术。

Spring AOP 增强类:

Spring 支持五种类型的增强:TrowsAdvice、AfterReturnAdvice、BeforeAdvice、DynamicIntroductionAdvice、MethodBeforeAdvice

按照增强在目标类中的连接点位置,可以分为以下5类:

(1)BeforeAdvice:前置增强,MethodBeforeAdvice 是目前可用的前置增强。

(2)AfterReturnAdvice:后置增强,表示在方法执行后实施增强。

(3)TrowsAdvice:异常抛出增强,目标代码抛出异常后实施增强。

(4)org.aopalliance.intercept.MethodInterceptor:环绕增强,表示在方法执行前后实施增强。

(5)IntroductionInterceptor:引介增强,表示在目标类中添加一些新的方法和属性。

前置增强:

通过一个 MethodBeforeAdvice(before 方法)创建具有横切逻辑和目录连接点信息的增强类,然后 ProxyFactory 代理工厂创建代理实例。

后置增强:

通过一个 AfterReturnAdvice(afterReturning 方法)创建具有横切逻辑和目录连接点信息的增强类,然后 ProxyFactory 代理工厂创建代理实例。

环绕增强:

通过一个 MethodInterceptor(invoke 方法)创建具有横切逻辑和目录连接点信息的增强类,然后 ProxyFactory 代理工厂创建代理实例。

异常抛出增强:

通过 TransactionManager(afterThrowing 方法) 这个异常抛出增强对业务方法进行增强处理,同一捕获抛出的异常并回滚事务。

必须采用以下签名形式定义异常抛出的增强方法:

void afterThrowing([Method method,Object[] orgs,Object target],Throwable) 前三个参数可选,但必须一起出现,最后一个参数 Throwable 可以是其子类,如:SQLExpection e,RuntimeException e

可以在异常抛出增强中定义多个 afterThrowing 方法,以匹配更多的异常。

引介增强:

引介增强是一种特殊的增强类型,它不是在目标方法周围织入增强,而是为目标类创建新的方法和属性。所以引介增强的连接点是类级别的,而非方法级别的。

切点:

上述增强中只描述了方位,导致增强会被织入所有方法中,使用切点就可以对连接点进行具体的定位,从而实现把增强织入目标类特定方法中。

pointcut 由 ClassFilter 和 MethodMatcher 构成。通过 ClassFilter 定位到特定类,再通过 MethodMatcher 定位到特定方法上。

对于方法匹配,Spring 提供了两种方法匹配器:静态方法匹配器动态方法匹配器

静态方法匹配去仅对方法名签名进行匹配,只会判别一次,而动态方法匹配器会在运行期间检查方法入参的值,性能影响大。isRuntime() 方法的返回值为 true 即为动态方法匹配器,反之静态。

切点类型:

(1)静态方法切点
(2)动态方法切点
(3)注解切点
(4)表达式切点:支持 AspectJ 切点表达式语法而定义的接口
(5)流程切点
(6)复合切点

切面类型:

一般切面(Advisor)包含横切逻辑代码,和连接点具体信息,理论上一个 Advice 也是一个切面,只不过这个切面太过宽泛。

切点切面pointAdvisor:代表具有切点的切面,包含 Pointcut 和 Advice 两个类。

自动创建代理:

Spring 利用 BeanPostProcessor 自动创建 bean 的代理,而无需使用 ProxyBeanFactory 进行配置。

BeanPostProcessor 的实现类可以分为三类:

(1)BeanNameAutoProxyCreator 基于 Bean 配置名规则自动代理创建器;

(2)DefaultAdvisorAutoProxyCreator 基于 Advisor 匹配机制的自动代理创建器;

(3)AnnotationAwareAspectJAutoProxyCreater 基于 Bean 中 AspectJ 注解标签的自动代理创建器;

你可能感兴趣的:(Spring AOP 笔记)