1.1 AOP概述 1.1.1 什么是AOP? AOP : 全称是Aspect Oriented Progamming既 : 面向切面编程.通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术. 简单的说它就是把我们程序重复的代码抽取出来,在需要执行的时候,使用动态代理的技术,在不修改源码的基础上,对我们的已有方法进行增强. 1.1.2 AOP的作用及优势 作用 : 在程序运行期间,不修改源码对已有方法进行增强. 优势 : 减少重复代码,提高开发效率,维护方便. 1.1.3 AOP的实现方式 : 使用动态代理技术 1.2.2.1 动态代理的特点 : 字节码随用随创建,随用随加载. 它与静态代理的区别也在于此.因为静态代理是字节码一上来就创建好,并完成加载. 装饰着模式就是静态代理的一种体现. 1.2.2.2 动态代理常用的有两种方式 基于接口的动态代理 提供者 : JDK官方的Proxy类. 要求 : 被代理来最少实现一个接口. 基于子类的动态代理 提供者 : 第三方的CGLib,如果报asmxxxx异常,需要导入asm.jar. 要求 : 被代理类不能用final修饰的类(最终类). 1.3 Spring中的AOP 1.3.1 关于代理的选择 在Spring中,框架根据目标类实现了接口决定采用哪种动态代理的方式. 1.3.2 AOP相关术语 Joinpoint(连接点) : 所谓连接点是指那些被拦截到的点.在Spring中,这些点值得是方法,因为spring只支持方法类型的连接点. Pointcut(切入点) : 所谓切入点是指我们要对那些Joinpoint进行拦截的定义. Advice(通知/增强) : 所谓通知是指拦截到Joinpoint之后所要做的事情就是通知. 通知的类型 : 前置通知,后置通知,异常通知,最终通知,环绕通知. Introduction(引介) : 是一种特殊的通知在不修改类代码的前提下,Introduction可以在运行期为类动态地添加一些方法或Field. Target(目的对象) : 代理的目标对象. Weaving(织入) : 是值把增强应用到目标对象来创建新的代理对象的过程. spring采用动态代理织入,而AspectJ采用编译器织入和类转载期织入. Proxy (代理) : 一个类被AOP织入增强后,就是产生一个结果代理类. Aspect(切面) : 是切入点和通知(引介) 的结合. 1.4 基于XML的AOP配置 1.4.1 导入包 1.4.2 准备接口 1.4.3 创建配置文件导入约束 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> </beans> 2.1.4第四步:把客户的业务层配置到spring容器中 <!-- 把资源交给spring来管理 --> <bean id="customerService" class="com.baidu.service.impl.CustomerServiceImpl"/> 2.1.5第五步:制作通知(增强的类) /** * 一个记录日志的工具类 */ public class Logger { /** * 期望:此方法在业务核心方法执行之前,就记录日志 */ public void beforePrintLog(){ System.out.println("Logger类中的printLog方法开始记录日志了。。。。"); } } 2.2配置步骤 2.2.1第一步:把通知类用bean标签配置起来 <!-- 把有公共代码的类也让spring来管理(把通知类也交给spring来管理) --> <bean id="logger" class="com.baidu.util.Logger"></bean> 2.2.2第二步:使用aop:config声明aop配置 <!-- aop的配置 --> <aop:config> <!-- 配置的代码都写在此处 --> </aop:config> 2.2.3第三步:使用aop:aspect配置切面 <!-- 配置切面 :此标签要出现在aop:config内部 id:给切面提供一个唯一标识 ref:引用的是通知类的bean的id --> <aop:aspect id="logAdvice" ref="logger"> <!--配置通知的类型要写在此处--> </aop:aspect> 2.2.4第四步:使用aop:before配置前置通知 <!-- 用于配置前置通知:指定增强的方法在切入点方法之前执行 method:用于指定通知类中的增强方法名称 ponitcut-ref:用于指定切入点的表达式的引用 --> <aop:before method="beforePrintLog" pointcut-ref="pt1"/> 2.2.5第五步:使用aop:pointcut配置切入点表达式 <aop:pointcut expression="execution(public void com.baidu.service.impl.CustomerServiceImpl.saveCustomer())" id="pt1"/> 2.3切入点表达式说明 execution: 匹配方法的执行(常用) execution(表达式) 表达式语法:execution([修饰符] 返回值类型 包名.类名.方法名(参数)) 写法说明: 全匹配方式: public void com.baid