Spring中的可插拔的组件技术,这些软件模块向横切面一样的穿插在了原有代码的执行流程中
Spring AOP
- Spring AOP - Aspect Oriented Programming 面向切面编程
-
1、AOP的关键概念
1.1、Spring AOP与AspectJ的关系
Eclipse AspectJ ,一种基于Java平台的面向切面编程的语言
- Spring AOP使用AspectJWeaver是实现类与方法匹配
- Spring AOP利用代理模式实现对象运行时功能扩展
几个关键概念 | Aspect | 切面,具体的可插拔组件功能类,通常一个切面只实现一个通用功能;切面:本质上就是一个标准的类,无需实现或继承其他的类,切面类中定义有具体的切面方法,切面方法就涉及到具体的功能扩展了(切面方法必须为public 范围值为void或Object,要根据具体的通知类型不同,书写不同的返回值,方法名可以自定义,但是参数必须是Join Point连接点)Join Point连接点是每一个切面方法必不可少的组成部分 | | —- | —- | | Target Class/Method | 目标类、目标方法,指真正要执行与业务相关的方法;Service、Dao中的哪些要增强的方法,作为切面,最终也是对这些目标方法进行增强 | | PonitCut | 切入点,使用execution表达式说明切面要作用在那些类上;决定了切面作用的范围 | | Join Point | 连接点,切面运行过程中是包含了目标类/方法元数据的对象;通过连接点可以获取到目标类/方法的信息 | | Advice | 通知,说明具体切面的执行时机,Spring包含了五种不同类型的通知;决定了切面方法执行的时机 |
切点决定了在什么地方;通知(advice)决定了在什么时间;连接点决定了在什么地方(目标方法)
1.2、AOP配置过程
依赖AspectJ
- 实现切面类/方法
- 配置Aspect Bean
- 定义PointCut(决定切面作用在系统的那些类上的哪些方法上)
- 配置Advice :决定切面方法什么时机才会被运行
1.3、Join Point核心方法
| 注解 | 说明 | | —- | —- | | Object getTarget() | 获取IOC容器内目标对象 | | Signature getSignature() | 获取目标方法 | | Object[] getArgs() | 获取目标方法参数 |
1.4、PointCut切点表达式
- public void com.imooc.service,UserService.createUser(形参1,形参2,…)
execution(public com.imooc .. .* (..))两个点表示通配符 ,任意数量,任意类型,public 可以省略
1.5、五种通知类型
| 注解 | 说明 | | —- | —- | | Before advice | 前置通知,目标方法执行前执行 | | After Returning Advice | 返回后通知,目标方法返回数据后执行;返回后通知和后置通知最大的不同是返回后通知可以接收到目标方法的返回值 | | After Throwing Advice | 异常通知,目标方法抛出异常会通知;相当于catch代码块 | | After Advice | 后置通知,目标方法运行后通知;相当于finally | | Around Advice | 最强大通知,自定义通知执行时机,可决定目标方法是否运行 |
特殊的”通知”(类似于通知的组件)-引介增强:是对类的增强,而非方法
- 引介增强允许在运行时为目标类增加新属性或方法
引介增强允许在运行时改变类的行为,让类随运行环境动态变更,可以让Java程序变得非常灵活
2、Spring AOP实现原理
Spring基于代理模式实现功能动态扩展,包含两种形式:
- 目标类拥有接口,通过JDK动态代理实现功能扩展。
- 目标类没有接口。通过CGLib组件实现功能扩展。
- 代理模式
- 代理模式通过代理对象对原对象实现功能的扩展、
- 必须要手动创建代理类的代理称为静态代理,最简单的使用方式,最麻烦的使用方式
- 代理模式通过代理对象对原对象实现功能的扩展、
静态代理:手动创建代理类,让代理类持有了目标对象的引用,代理类和委托类要实现相同的接口
2.1、AOP底层原理-JDK动态代理
可以根据要实现的接口,按照接口的结构自动的去生成相应的代理类,完成目标方法的扩展,因为代理类实在目标类执行的过程中动态生成的,所以称为动态代理类。
静态代理需要手写代理类,动态代理是根据接口的结构自动的在运行时内存中进行生成。
- UserService userServiceProxy=Proxy.newProxy Instance();userServiceProxy.createUser()
- 生成$Proxy0.class
- 确定代理类的包名 :com.sun.proxy
- 确定代理类的类名:com.sun.proxy.$Proxy0
- 确定代理类的类名:$Proxy生成代理类的代码 ProxyGenerator.generatorProxyClass
2.2、Spring AOP实现原理
- 如果目标类实现了接口,则Spring 优先底层使用JDK动态代理来生成目标类的代理从而来实现功能的扩展
如果目标类没有实现接口,则自动使用CGLib,通过继承的方式对目标类进行扩展
3、总结与回顾
Spring AOP(面向切面编程):是在不修改源代码的情况下扩展程序的技术
- Eclipse AspectJ,一种基于Java平台的面向切面编程的语言
- Spring AOP使用AspectJWeaver实现类与方法匹配
- Spring AOP利用代理模式实现对象运行时功能扩展
- AOP配置过程
- 依赖AspectJ
- 实现切面类/方法
- 配置AspectBean
- 定义PointCut
- 配置Advice
- Spring AOP的实现原理 (面试重点)
- Spring 基于代理模式实现功能动态扩展,包含两种形式
- 目标类拥有接口,通过JDK动态代理实现功能扩展
- 目标类没有接口,通过CGLib组件实现功能扩展