AOP(面向切面编程)
1、AOP概念:
面向切面编程,指扩展功能不修改源代码,将功能代码从业务逻辑代码中分离出来。
主要功能:日志记录,性能统计,安全控制,事务处理,异常处理等等。
主要意图:将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。
2、AOP特点:
采用横向抽取机制,取代了传统纵向继承体系重复性代码。
3、AOP底层实现:
AOP底层使用动态代理实现。包括两种方式:
使用JDK动态代理实现。
使用cglib来实现
JDK动态代理实现:
只能对实现了接口的类生成代理,而不是针对类,该目标类型实现的接口都将被代理。原理是通过在运行期间创建一个接口的实现类来完成对目标对象的代理。步骤如下:
定义一个实现接口InvocationHandler的类
通过构造函数,注入被代理类
实现invoke( Object proxy, Method method, Object[] args)方法
在主函数中获得被代理类的类加载器
使用Proxy.newProxyInstance( )产生一个代理对象
通过代理对象调用各种方法
cglib动态代理实现:
针对类实现代理,对是否实现接口无要求。原理是对指定的类生成一个子类,覆盖其中的方法,因为是继承,所以被代理的类或方法最好不要声明为final类型。
定义一个实现了MethodInterceptor接口的类
实现其intercept()方法,在其中调用proxy.invokeSuper( )
代理方式的选择:
如果目标对象实现了接口,默认情况下回采用JDK的动态代理实现AOP,也可以强制使用cglib实现AOP
如果目标对象没有实现接口,必须采用cglib库,Spring会自动在JDK动态代理和cglib之间转换
静态代理和动态代理的区别:
静态代理:自己编写创建代理类,然后再进行编译,在程序运行前,代理类的.class文件就已经存在了。
动态代理:在实现阶段不用关心代理谁,而在运行阶段(通过反射机制)才指定代理哪一个对象。
- 名词
- 连接点 JoinPoint : 可以被切入的点,通常是方法。连接点对象描述了当前连接点的信息,比如,目标对象、方法信息、参数等等
- 通知 Advice : 需要向切面加入的功能
- 引入 Introduction: 对目标对象添加方法和属性
- 切面 Aspect : 将切面模块化,包含了要切入的功能,切入点等等
- 目标对象 Target: 切面通知的对象
- 代理 Proxy : AOP的一种实现方式
- 织入 Weaving: 将切面应用到目标对象的过程
- 切入点 PointCut : 需要织入通知的连接点,通常用SPEL描述
- 实现
- 通知 (SpringBean)
- 前 before JoinPoint
- 后 after JoinPoint
- 环绕 around ProceedingJoinPoint
- 异常 after-throwing
- 返回 after-returning
- 配置
- 包扫描
- aop 关联到通知
- pointcut
- 通知方法
- 通知 (SpringBean)
- 应用场景
- 权限验证
- 性能追踪
- 日志追踪
- 异常处理
- 事务 => Spring 的声明式事务管理
- 缓存
- 懒加载
Spring的配置方式(提供元数据metadata)
-
纯XML
-
纯Java
-
注解(标记 需要spring管理的类以及需要spring依赖注入的属性) + 包扫描(XML | Java配置类)
-
其他特定功能的注解
- @Aspect @Pointcut @Before @After @EnableAspectJAutoProxy … AOP的注解
AOP的实现
- 代理模式 Proxy模式
- 静态代理
- 动态代理
- 通过InvocationHandler 实现方法拦截加入代理功能
- 通过Proxy类创建动态代理实例
- 当调用生成的代理实例时,会被invocationHandler的方法拦截,方法实现就是代理的内容
原文:https://blog.csdn.net/qq_25827845/article/details/75208354