在现在的开发中使用这种方案比较多.
在spring2.0以后它支持jdk1.5注解,而整合aspectj后可以使用aspectj语法,可以简化开发。
Aspect:切面 =切点+通知(多个切点与多个通知的组合)
AspectJ 它是一个第三方框架,spring从2.0后可以使用aspectJ框架的部分语法.
AspectJ框架它定义的通知类型有6种
1.前置通知Before 相当于BeforeAdvice
2.后置通知AfterReturning 相当于AfterReturningAdvice
3.环绕通知 Around 相当于MethodInterceptor
4.抛出通知AfterThrowing 相当于ThrowAdvice
5.引介通知DeclareParents 相当于IntroductionInterceptor
6.最终通知After 不管是否异常,该通知都会执行
相比spring 的传统AOP Advice多了一个最终通知
基于xml配置方案(重点必会)
第一步:创建目标(target)
第二步:创建通知(增强advice)
注意:在aspectJ中它的增强可以不实现任何接口,只需要定义出增强功能(方法)
第三步:在spring的xml配置文件中来配置
<aop:config>下的<aop:aspect>是aspectJ框架用来声明切面的.
前置通知
后置通知
环绕通知
异常抛出:
注意:目标行为只有抛出了异常之后才会执行这个增强方法
最终通知:
无论是否有异常,最终通知都会执行
关于通知上的参数
1. 在前置通知上可以添加joinPoint参数
通过joinPoint可以获取目标相关的信息
使用前置通知可以完成日志记录,权限控制
2. 在后置通知上添加的参数
第二个参数val它可以获取目标方法的返回值
注意:需要在配置文件中配置returning属性
使用后置通知也可以完成日志记录
3. 环绕通知上的参数
它是我们开发中应用最多的,可以完成日志操作,权限操作,性能监控,事务管理
4. 抛出异常通知上的参数
第二个参数Throwable它是用于接收抛出的异常
注意:需要在配置文件中配置throwing属性
5. 最终通知上的参数
可以使用最终通知完成资源释放
关于代理方式的选择
在spring的aop开发中,它是用的是代理方案,代理的实现有两种:
1. jdk的proxy
2. Cglib
Spring 框架默认情况下,会对有接口的类使用proxy代理,没有接口的类使用cglib代理.
Proxy-target-class的属性值默认是false,它代表有接口使用proxy代理
问题:如果现在要对目标使用cglib代理(不考虑是否有接口)?
只需要将proxy-target-class的值设置为true.
基于annotation方案(重点必会)
第一步:编写目标target
在spring的配置文件中配置注解扫描
第二步:编写增强(advice)
使用@Aspect来声明切面
使用@Before来声明前置通知
注意:必须要在spring的配置文件中开启aspectJ注解自动代理功能
第三:测试
其他通知类型及参数
后置通知
环绕通知
异常抛出通知
最终通知
使用@Pointcut注解定义切点
在每一个通知中定义切点,工作量大,不方便维护,我们可以使用@pointcut来声明切点
切点允许逻辑运算 例如mypointcut()||mypointcut1()
关于代理方式选择
Proxy-target-class默认值是false,代表的是如果目标类是有接口的使用jdk的proxy代理,如果没有接口使用cglib
如果将proxy-target-class设置为true,那么不管目标类是实现了接口,都会使用cglib进行代理