没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
试读
20页
Spring AOP(面向切面编程)作为Spring框架的一个重要部分,为Java开发者提供了一个强大而灵活的工具来切入代码执行流程,实现关注点的分离。通过详细解析Spring AOP的源码,本文揭示了其背后的核心原理和实现机制。Spring AOP主要基于动态代理模式,它允许开发者在不改变原有代码结构的情况下,增加额外的行为。这主要通过定义“切面(Aspects)”和“通知(Advices)”来实现,其中切面定义了何时以及如何插入额外的行为,而通知则描述了这个额外行为本身。Spring AOP支持不同类型的通知,如前置通知(Before)、后置通知(After)、返回后通知(After-returning)、抛出异常后通知(After-throwing)和环绕通知(Around)。这种机制使得开发者可以在运行时动态地应用这些通知到目标对象,而无需修改其源码。通过对Spring AOP源码的深入分析,我们可以更好地理解其内部工作原理,从而在实际开发中更加灵活和高效地使用这一强大的编程范式。
资源推荐
资源详情
资源评论
Spring-AOP源码
Spring-AOP源码
AOP,AspectJ,SpringAOP前世今生
Spring1.2中的配置
Spring2.0@AspectJ配置
Spring2.0schema-based配置
AspectJ编译方式实现AOP:
springaop源码解析
一、切面类的解析
二、创建代理
三、代理类的调用
AOP,AspectJ,SpringAOP前世今生
我们先来把它们的概念和关系说说清楚,我们学习的Spring-AOP其实冰山一角,但是AOP还有很多的相关内容需要了
解。
AOP要实现的是在我们原来写的代码的基础上,进行一定的包装,如在方法执行前、方法返回后、方法抛出异
常后等地方进行一定的拦截处理或者叫增强处理。
AOP的实现并不是因为Java提供了什么神奇的钩子,可以把方法的几个生命周期告诉我们,而是我们要实现
一个代理,实际运行的实例其实是生成的代理类的实例。
作为Java开发者,我们都很熟悉AspectJ这个词,甚至于我们提到AOP的时候,想到的往往就是
AspectJ,即使你可能不太懂它是怎么工作的。这里,我们把AspectJ和SpringAOP做个简单的对比:
SpringAOP:
AOP术语解释
AOP术语解释
https://www.processon.com/view/link/5ecca5ebe0b34d5f262eae3a
SpringAop:
它基于动态代理来实现。默认地,如果使用接口的,用JDK提供的动态代理实现,如果没有接口,使用
CGLIB实现。大家一定要明白背后的意思,包括什么时候会不用JDK提供的动态代理,而用CGLIB实现。
Spring3.2以后,spring-core直接就把CGLIB和ASM的源码包括进来了,这也是为什么我们不需要显式
引入这两个依赖
Spring的IOC容器和AOP都很重要,SpringAOP需要依赖于IOC容器来管理。
SpringAOP只能作用于Spring容器中的Bean,它是使用纯粹的Java代码实现的,只能作用于bean的方
法。
Spring提供了AspectJ的支持,但只用到的AspectJ的切点解析和匹配。
很多人会对比SpringAOP和AspectJ的性能,SpringAOP是基于代理实现的,在容器启动的时候需要生成
代理实例,在方法调用上也会增加栈的深度,使得SpringAOP的性能不如AspectJ那么好。
AspectJ:
AspectJ出身也是名门,来自于Eclipse基金会,link:https://www.eclipse.org/aspectj
属于静态织入,它是通过修改代码来实现的,它的织入时机可以是:
Compile-timeweaving:编译期织入,如类A使用AspectJ添加了一个属性,类B引
用了它,这个场景就需要编译期的时候就进行织入,否则没法编译类B。
Post-compileweaving:编译后织入,也就是已经生成了.class文件,或已经打成jar包
了,这种情况我们需要增强处理的话,就要用到编译后织入。
Load-timeweaving:指的是在加载类的时候进行织入,要实现这个时期的织入,有几
种常见的方法。1、自定义类加载器来干这个,这个应该是最容易想到的办法,在被织入类加
载到JVM前去对它进行加载,这样就可以在加载的时候定义行为了。2、在JVM启动的时候
指定AspectJ提供的agent:-javaagent:xxx/xxx/aspectjweaver.jar。
AspectJ能干很多SpringAOP干不了的事情,它是AOP编程的完全解决方案。SpringAOP致力于解决的
是企业级开发中最普遍的AOP需求(方法织入),而不是力求成为一个像AspectJ一样的AOP编程完全解决方
案。
因为AspectJ在实际代码运行前完成了织入,所以大家会说它生成的类是没有额外运行时开销的。
SpringAOP
首先要说明的是,这里介绍的SpringAOP是纯的Spring代码,和AspectJ没什么关系,但是Spring延用了AspectJ
中的概念,包括使用了AspectJ提供的jar包中的注解,但是不依赖于其实现功能。
后
面
介
绍的
如
@Aspect
、
@Pointcut
、
@Before
、
@After
等
注
解
都
是来
自
于
AspectJ
,
但
是
功
能
的
实
现
是
纯
SpringAOP
自
己实
现
的
。
下面我们来介绍SpringAOP的使用方法,先从最简单的配置方式开始说起,这样读者想看源码也会比较容易。
目前SpringAOP一共有三种配置方式,Spring做到了很好地向下兼容,所以大家可以放心使用。
Spring1.2基于接口的配置:最早的SpringAOP是完全基于几个接口的,想看源码的同学可以从这里起步。
Spring2.0schema-based配置:Spring2.0以后使用XML的方式来配置,使用命名空间<aop ></aop>
Spring2.0@AspectJ配置:使用注解的方式来配置,这种方式感觉是最方便的,还有,这里虽然叫
做@AspectJ,但是这个和AspectJ其实没啥关系。
Spring1.2中的配置
这节我们将介绍Spring1.2中的配置,这是最古老的配置,但是由于Spring提供了很好的向后兼容,以及很多人根本
不知道什么配置是什么版本的,以及是否有更新更好的配置方法替代,所以还是会有很多代码是采用这种古老的配置方
式的(比如声明式事务),这里说的古老并没有贬义的意思。
下面用一个简单的例子来演示怎么使用Spring1.2的配置方式。
首先定义需要被增强的类:
接口:Calculate.java,实现类:TulingCalculate.java
1
2 /**
3 *计算类接口
4 *Createdbyxslson2019/6/10.
5 */
6 publicinterfaceCalculate{
7
8 /**
9 *加法
10 *@paramnumA
11 *@paramnumB
12 *@return
13 */
14 intadd(intnumA,intnumB);
15
16 /**
17 *减法
18 *@paramnumA
19 *@paramnumB
20 *@return
21 */
22 intsub(intnumA,intnumB);
23
24 /**
25 *除法
26 *@paramnumA
27 *@paramnumB
28 *@return
29 */
30 intdiv(intnumA,intnumB);
31
32 /**
33 *乘法
34 *@paramnumA
35 *@paramnumB
36 *@return
37 */
38 intmulti(intnumA,intnumB);
39
40 intmod(intnumA,intnumB);
41 }
1
2 /**
3 *Createdbyxslson2019/6/10.
4 */
5 @Component
6 publicclassTulingCalculateimplementsCalculate{
7
8 publicintadd(intnumA,intnumB){
9
10 System.out.println("执行目标方法:add");
11 System.out.println(1/0);
12 returnnumA+numB;
13 }
14
15 publicintsub(intnumA,intnumB){
16 System.out.println("执行目标方法:reduce");
17 returnnumA‐numB;
18 }
19
20 publicintdiv(intnumA,intnumB){
21 System.out.println("执行目标方法:div");
22 returnnumA/numB;
23 }
24
25 publicintmulti(intnumA,intnumB){
26 System.out.println("执行目标方法:multi");
27
28 returnnumA*numB;
29 }
30
31 publicintmod(intnumA,intnumB){
32 System.out.println("执行目标方法:mod");
33
34 intretVal=((Calculate)AopContext.currentProxy()).add(numA,numB);
35 //intretVal=this.add(numA,numB);
36
37 returnretVal%numA;
38
39 //returnnumA%numB;
40 }
接下来,我们定义advice或Interceptor,我这里提供2个:
advice
是
我
们
接
触
的第
一
个
概
念
,
记
住
它
是
干
什么
用的
。
TulingLogAdvice.java
1 publicclassTulingLogAdviceimplementsMethodBeforeAdvice{
2 @Override
3 publicvoidbefore(Methodmethod,Object[]args,Objecttarget)throwsThrowable{
4 StringmethodName=method.getName();
5 System.out.println("执行目标方法【"+methodName+"】的<前置通知>,入参"+Arrays.asList(args));
6 }
7 }
TulingLogInterceptor.java
1
2 /***
3 *@Author徐庶QQ:1092002729
4 *@Slogan致敬大师,致敬未来的你
剩余19页未读,继续阅读
资源评论
光芒软件工匠
- 粉丝: 789
- 资源: 64
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功