spring之AOP编程
AOP介绍
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP(面向对象编程)的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码
经典应用:事务管理、性能监视、安全检查、缓存、日志等
Spring AOP使用纯Java实现,不需要专门的编译过程和类加载器,在运行期通过代理方式向目标类织入增强代码
AspectJ是一个基于Java语言的AOP框架,Spring2.0开始,Spring AOP引入对Aspect的支持,AspectJ扩展了Java语言,提供了一个专门的编译器,在编译时提供横向代码的织入
AOP实现原理
aop底层将采用代理机制进行实现。
接口 + 实现类:spring采用 jdk 的动态代理Proxy。
未实现接口的类:spring 采用 cglib字节码增强。
AOP术语
1.target:目标类,需要被代理的类。例如:UserService
2.Joinpoint(连接点):所谓连接点是指那些可能被拦截到的方法。例如:所有的方法
3.PointCut 切入点:已经被增强的连接点。例如:addUser()
4.advice 通知/增强,增强代码。例如:after、before
5. Weaving(织入):是指把增强advice应用到目标对象target来创建新的代理对象proxy的过程.
6.proxy 代理类
7. Aspect(切面): 是切入点pointcut和通知advice的结合
一个线是一个特殊的面。
一个切入点和一个通知,组成成一个特殊的面。
AOP联盟通知类型
AOP联盟为通知Advice定义了org.aopalliance.aop.Advice
Spring按照通知Advice在目标类方法的连接点位置,可以分为5类
前置通知org.springframework.aop.MethodBeforeAdvice
在目标方法执行前实施增强
后置通知 org.springframework.aop.AfterReturningAdvice
在目标方法执行后实施增强
环绕通知 org.aopalliance.intercept.MethodInterceptor
在目标方法执行前后实施增强
异常抛出通知 org.springframework.aop.ThrowsAdvice
在方法抛出异常后实施增强
引介通知org.springframework.aop.IntroductionInterceptor
在目标类中添加一些新的方法和属性
springAOP编程:全自动
如果用上图所示的配置实现aop,那么切面类就需要实现特定的接口,这是为了表明该切面类要的切入点是在方法的前面还是后面或者环绕等,例:
AspectJ
介绍
AspectJ是一个基于Java语言的AOP框架
Spring2.0以后新增了对AspectJ切点表达式支持
@AspectJ 是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面
新版本Spring框架,建议使用AspectJ方式来开发AOP
主要用途:自定义开发
切入点表达式
execution() 用于描述方法,例,execution(*com.itheima.crm.*.service..*.*(..))
AspectJ 通知类型
个数:6种,知道5种,掌握1中。
before:前置通知(应用:各种校验)
在方法执行前执行,如果通知抛出异常,阻止方法运行
afterReturning:后置通知(应用:常规数据处理)
方法正常返回后执行,如果方法中抛出异常,通知无法执行
必须在方法执行后才执行,所以可以获得方法的返回值。
around:环绕通知(应用:十分强大,可以做任何事情)
方法执行前后分别执行,可以阻止方法的执行
必须手动执行目标方法
afterThrowing:抛出异常通知(应用:包装异常信息)
方法抛出异常后执行,如果方法没有抛出异常,无法执行
after:最终通知(应用:清理现场)
方法执行完毕后执行,无论方法中是否出现异常
AspectJ基于xml的使用
配置如下
对比于上面的springAOP编程,可以发现,在配置上的区别是,aspectj的配置中声明了切面类的某个方法要被用于什么时机,例如 aop:before,而springAOP编程中则没有声明这一点,它实现这一效果是通过让切面类去是实现特定的接口。
aspectj中的切面类不需要实现特定的接口,所以他们可以随意定义方法,这样就显得更加自由,并且aspectj的配置能够确定到切面类中的某个方法,这样我们就可以在一个切面类中定义多个方法,而每个方法都可用于不同的切入时机,例如,一个方法用于before,一个方法用于after-Returning。
至于springAOP编程能不能实现该效果,我没有去实验,但是估计是可以的,因为我们可以通过实现多个特定的接口,也就是在同一个切面类中实现好几个特定的方法,多种时机下复用这个切面类,应该也可以达到该效果。
下面是切面类中各方法参数与xml配置的统一
AspectJ基于注解的使用
替换bean
替换aop
替换通知
aop注解总结
@Aspect 声明切面,修饰切面类,从而获得通知。
通知
@Before前置
@AfterReturning后置
@Around环绕
@AfterThrowing抛出异常
@After最终
切入点
@PointCut,修饰方法private void xxx(){} 之后通过“方法名”获得切入点引用