Spring AOP使用的是代理模式

AOP是什么?

面向切面编程,把业务逻辑和横切的问题进行分离,从而达到解耦的目的,使代码的重用性和开发效率高(目的是重用代码,把公共的代码抽取出来)" 横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块(如日志、登录校验),并将其命名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。

使用"横切"技术,AOP 把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点(日志、权限校验)。

 

应用场景

  • 日志记录
  • 权限校验
  • 效率检查
  • 事务管理

 

底层原理

  • JDK动态代理:动态代理是在程序运行时通过反射机制动态创建的。主要是用到了java.lang.reflect.Proxy类和InvocationHandler接口。
  • CGLIB代理: 采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。但因为采用的是继承,所以不能对final修饰的类进行代理。

JDK 创建代理有一个限制,就是只能为接口创建代理实例,而对于没有通过接口定义业务方法的类,则可以通过 CGLib 创建动态代理。

 

是编译时期进行织入,还是运行期进行织入?

    运行期,生成字节码,再加载到虚拟机中,JDK是利用反射原理,CGLIB使用了ASM原理。

 

初始化时期织入还是获取对象时织入?

    初始化的时候,已经将目标对象进行代理,放入到spring 容器中

 

spring AOP 默认使用jdk动态代理还是cglib?

    要看条件,如果实现了接口的类,是使用jdk。如果没实现接口,就使用cglib。

 

spring AOP 和 AspectJ的关系?

两者都是为了实现AOP这个目的,而出现的技术,spring aop 参考 AspectJ编程风格

AspectJ:是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法,它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。