常用的动态代理结束
- jdk 代理,基于接口的动态代理技术,利用拦截器(必须实现invocationHandler)加上反射机制生成一个代理接口的匿名类,在调用具体方法前调用invokeHandler来处理,从而实现方法的加强。
- cglib 代理,基于父类动态代理技术,动态生成一个要代理的子类,子类要重写代理类的所有不是final的方法,在子类中采用方法拦截技术拦截所有的父类方法的调用,顺势加入横切逻辑,对方法进行加强。
JDK动态代理方式
jdk 工厂类
类加载器,被代理类所需要实现的接口,当代理对象调用接口中的任意方法,都会执行invocationHander 中的invoke方法
Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces, InvocationHander h);
被代理类至少实现一个接口 cglib 动态代理,基于父类,不能被final 修饰。
AOP
AOP是aspect Oriented Programming 面向切面编程,利用AOP 可以对业务逻辑的各个部分进行隔离,各部分业务逻辑的耦合度降低,好处
- 在程序运行期间,在不修改源码的情况下对方法进行功能增强
- 逻辑清晰,开发核心业务的时候,不必关注增强业务的代码
- 减少重复代码,提高开发效率 ## AOP 底层实现 AOP的地城是通过Spring 提供的动态代理技术实现的,代理对象方法执行时进行增强功能的接入,再去调用目标方法,实现功能的增强
相关概念
- Target 代理的目标对象
- Proxy 一个类被AOP加入增强后,实现一个结果代理类
- joinpoint 所谓链接点指的是哪些被拦截的点,在 spring中,这些点指的是方法,因为 spring只支持方法类型的链接点
- pointcut 我们对哪些joinpoint 进行拦截
- advice 指拦截到joinpoint 之后要做的事情就是通知,分类,前置,后置,异常,最终,环绕
AOP 开发明确事项
开发阶段
- 编写核心业务代码
- 把公用代码抽取出来,制作成通知
- 在配置文件中,声明切入点与通知简单的关系
运行阶段(spring 框架完成)
spring框架监控切入点方法的执行,一旦监控的切入点方法被允许,使用代理机制,动态创建目标对象的代理对象,根据通知类别,在代理对象的对应位置,将通知对应的功能织入,完成完整的代码逻辑运行。
底层代理实现
在 spring中,框架会根据目标类是否实现了接口来决定采用哪种动态代理的方式
当Bean实现接口时,会用JDK代理模式
当Bean没有实现接口,用cglib实现(可以强制使用cglib(在spring 配置中加入
基于XML 的AOP开发
切点表达式
表达式语法: execution([修饰符] 返回值类型 包名.类名.方法名(参数))
切点表达式抽取
当多个增强的切点表达式相同时,可以将切点表达式进行抽取,在增强中使用pointcut-ref 属性代替pointcut属性来引用抽取后的切点表达式
通知类型
|名称|标签|说明|
|前置通知|<aop:before>|前置通知,增强方法在切入点方法之前|
|后置通知|<aop:afterReturing>|后置通知,增强方法在切入点方法之后|
|异常通知|<aop:afterThrowing>|异常通知,增强方法出现异常之后|
|最终通知|<aop:after>|最终通知,无论切入点方法是否有异常|
|环绕通知|<aop:around>|环绕通知,手动控制增强代码在什么时候执行|
通常情况下,环绕通知自都是独立使用