SpringAOP和代理模式
学习 Spring 的过程中,不可避免要掌握代理模式。这篇文章总结一下代理模式。顾名思义,代理,就是你委托别人帮你办事,所以代理模式也有人称作委托模式的。
java的设计模式中有一项设计模式叫做代理模式,所谓代理模式,就是通过代理方来操作目标对象,而不是自己直接调用。代理又分为静态代理和动态代理,静态代理就是针对每个被代理对象写一个代理类,操作不够优雅;动态代理,可以根据接口动态的生成代理类,这动态生成的类不需要自己书写,jdk帮你完成了。
动态代理基于反射机制
Spring面向切面编程
1.1 什么是 AOP
AOP (Aspect Orient Programming),直译过来就是 面向切面编程。AOP 是一种编程思想,是面向对象编程(OOP)的一种补充。面向对象编程将程序抽象成各个层次的对象,而面向切面编程是将程序抽象成各个切面。
1.2 为什么需要 AOP
想象下面的场景,开发中在多个模块间有某段重复的代码,我们通常是怎么处理的?显然,没有人会靠“复制粘贴”吧。在传统的面向过程编程中,我们也会将这段代码,抽象成一个方法,然后在需要的地方分别调用这个方法,这样当这段代码需要修改时,我们只需要改变这个方法就可以了。然而需求总是变化的,有一天,新增了一个需求,需要再多出做修改,我们需要再抽象出一个方法,然后再在需要的地方分别调用这个方法,又或者我们不需要这个方法了,我们还是得删除掉每一处调用该方法的地方。实际上涉及到多个地方具有相同的修改的问题我们都可以通过 AOP 来解决。
1.3 AOP 实现分类
AOP 要达到的效果是,保证开发者不修改源代码的前提下,去为系统中的业务组件添加某种通用功能。AOP 的本质是由 AOP 框架修改业务组件的多个方法的源代码,看到这其实应该明白了,AOP 其实就是前面一篇文章讲的代理模式的典型应用。
按照 AOP 框架修改源代码的时机,可以将其分为两类:
- 静态 AOP 实现, AOP 框架在编译阶段对程序源代码进行修改,生成了静态的 AOP 代理类(生成的 *.class 文件已经被改掉了,需要使用特定的编译器),比如 AspectJ。
- 动态 AOP 实现, AOP 框架在运行阶段对动态生成代理对象(在内存中以 JDK 动态代理,或 CGlib 动态地生成 AOP 代理类),如 SpringAOP。
面向切面编程
Pointcut表示切面执行的位置
切入点表达式语法execution(访问权限 返回值类型 方法名(方法参数) 异常类型)
可以用*表示通配符
…用于方法参数,表示参数类型任意,参数数量任意
+用于类名和接口名之后,表示当前类/子类,接口类/实现类
返回值类型和方法名必填,其余可省略
execution(* set*(..))//指定切入点在任意一个set开头的方法前
方法名可用全路径名称,包名.类名.方法名,同一包下也可以只用方法名
如何使用AOP
新建maven项目
导入依赖spring-context ,spring-aspect
创建业务接口,实现类
创建切面类
1)在切面类上@Aspect注解
2)在切面类定义方法表示切面功能
3)在切面方法上@xxx("value=切入点表达式")
创建spring配置文件
1)声明目标对象
2)声明切面对象
3)声明生成自动代理
AOP三要素,时间,位置,对象
通过xml获取容器,通过容器生成代理对象,由代理对象执行目标方法
@Before前置通知public void 切面方法可以用JoinPoint作为第一个参数,也只能有这一个参数,相当于反射的Method,spring会自动配置JointPoint
@AfterReturning后置通知public void 可以用JoinPoint作为第一个参数,可以获取目标方法的执行结果返回值,在参数中传入(Object res)在注解中声明同名参数,spring自动传入参数
@Around 环绕通知public 必须有返回值,必须要参数ProceedingJoinPoint,用于执行方法。当使用环绕通知方法,用环绕通知方法取代了原方法。可以在目标方法前后增强功能,可以控制目标方法是否执行,可以修改目标方法的结果,ProceedingJoinPoint.proceed()执行目标方法