Spring的Aop
什么是aop
Aop:Aspect Oriented Programming面向切面编程,Aop采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视、事务管理、安全检查、缓存)
1.传统方式的实现形式
如图所示,假如我们要在save方法执行之前,进行一个权限校验,一般处理方法是在类中新建一个校验方法,然后去调用即可。但是,假如有100个这样的方法需要进行权限校验,那么岂不是得写100个权限校验方法。这样非常不好。
传统的实现形式:采取纵向继承的方式,如下图所示。
在父类中实现权限校验方法,然后使得每个需要进行权限校验的方法去继承它,然后在自己类中调用即可。
2.Aop的解决办法:横向抽取机制
对UserDaoImpl产生一个代理类Proxy,这两个类相当于都实现了UserDao接口,那么我们就可以在Proxy类中对save方法进行代码的增强,故Aop的底层实现其实就是代理机制。
3.Aop相关概念
Advice(通知):分为前置通知、后置通知、异常通知、环绕通知、最终通知
Intoduction(引介):引介是一种特殊的通知,在不修改类代码的前提下,Introduction可以在运行期为类动态地添加一些方法或field
4.Aop底层实现原理
- JDK动态代理:
2.使用第三方的CGLIB:
5.代理知识总结
- Spring在运行期,生成动态代理对象,不需要特殊的编译器
- Spring Aop的底层就是通过JDK动态代理或者CGlib动态代理技术 为目标Bean执行横向织入
- 若目标对象实现了若干接口,spring则使用JDK的java.lang.reflect.Proxy类代理
- 如目标对象没有实现任何接口,spring使用CGLIB库生成目标对象的子类
- 程序中应优先对接口创建代理,便于程序解耦维护
- 标记为final的方法,不能被代理,因为无法被进行覆盖
- JDK动态代理,是针对接口生成的子类,接口中方法不能使用final修饰
- CGLIB是针对目标类产生子类,因此类或方法不能使用final修饰
6.Spring中的Aop
开发时需要引入的jar包:aopalliance包、spring-aop包
Aop联盟为通知定义了org.aopalliance.aop.Interface.Advice
Spring按照通知Advice在目标类方法的连接点位置,可以分为5类
- 前置通知–org.springframework.aop.MethodBeforeAdvice
- 后置通知–org.springframework.aop.AfterReturningAdvice
- 环绕通知–org.springframework.aop.MethodInterceptor
- 异常抛出通知–org.springframework.aop.ThrowsAdvice
- 引介通知–org.springframework.aop.IntroductionInterceptor
- 在目标类中添加一些新的方法或属性
7.Spirng的传统Aop的自动代理
由于上面第6点说到的方法,每一个需要产生代理的对象,都需要在配置文件中去配置一个ProxyFactoryBean,仍然非常的复杂,为了解决这一类问题,就产生了自动代理。
解决方案:自动创建代理
– BeanNameAutoProxyCreator 根据Bean名称创建代理,例如对所有Dao结尾的Bean进行增强
– DefaultAdvisorAutoProxyCreator 根据Advisor本身包含信息创建代理
– AnnotationAwareAspectJAutoProxyCreator 基于Bean中的AspectJ注解进行自动代理
- 基于Bean名称的自动代理
- 基于切面信息的自动代理
具体可见项目: