1、What?
AOP,面向切面编程编程
- OOP面向对象编程的模式,OOP的主要功能是数据封装、继承和多态。OOP把系统看做多个对象的交互
- AOP是一种新的编程方式,AOP把系统分解为不一样的关注点,或者称之为切面
相关概念:代理
- Aspect:切面,即一个横跨多个核心逻辑的功能,或者称之为系统关注点
- Joinpoint:链接点,即定义在应用程序流程的何处插入切面的执行
- Pointcut:切入点,即一组链接点的集合
- Weaving:织入,指将切面整合到程序的执行流程中
- Target Object:目标对象,即真正执行业务的核心逻辑对象
拦截器有如下类型:对象
- @Before:这种拦截器先执行拦截代码,再执行目标代码。若是拦截器抛异常,那么目标代码就不执行了;
- @After:这种拦截器先执行目标代码,再执行拦截器代码。不管目标代码是否抛异常,拦截器代码都会执行;
- @AfterReturning:和@After不一样的是,只有当目标代码正常返回时,才执行拦截器代码;
- @AfterThrowing:和@After不一样的是,只有当目标代码抛出了异常时,才执行拦截器代码;
- @Around:能彻底控制目标代码是否执行,并能够在执行先后、抛异常后执行任意拦截代码,能够说是包含了上面全部功能。
2、How?
生产中使用注解装配AOP,不要使用AspectJ的相似execution( xxx.Xyz.(..))这样的复杂注解继承
3、Why?
对于AOP的织入,有3种方式:接口
- 编译期:在编译时,由编译器把切面调用编译进字节码,这种方式须要定义新的关键字并扩展编译器,AspectJ就扩展了Java编译器,使用关键字aspect来实现织入;
- 类加载器:在目标类被装载到JVM时,经过一个特殊的类加载器,对目标类的字节码从新“加强”;
- 运行期:目标对象和切面都是普通Java类,经过JVM的动态代理功能或者第三方库实现运行期动态织入。
Spring的AOP实现就是基于动态代理:get
- Spring对接口类型使用JDK动态代理,对普通类使用CGLIB建立子类。若是一个Bean的class是final,Spring将没法为其建立子类。
自动加super()的功能是Java编译器实现的,它发现你没加,就自动给加上,发现你加错了,就报编译错误。但实际上,若是直接构造字节码,一个类的构造方法中,不必定非要调用super()。Spring使用CGLIB构造的Proxy类,是直接生成字节码,并无源码-编译-字节码这个步骤,因此:编译器
- Spring经过CGLIB建立的代理类,不会初始化代理类自身继承的任何成员变量,包括final类型的成员变量!