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文件。