2026-10-22 09:50:42
尚学堂百战程序员之AOP面向切面编程
AOP(Aspect Oriented Programming),即面向切面编程,是面向对象编程OOP(Object Oriented Programming)的补充和完善。它通过一种称为“横切”的技术,将那些影响了多个类的公共行为封装到一个可重用模块,即“Aspect”切面中,以减少系统的重复代码,降低模块之间的耦合度,提高系统的可操作性和可维护性。
一、AOP的核心概念
连接点(Joinpoint):
表示需要在程序中插入横切关注点的扩展点。
连接点可能是类初始化、方法执行、方法调用、字段调用或处理异常等。
在Spring中,只支持方法执行连接点,因此定义要被增强的方法为切入点即可。
切入点(Pointcut):
切入点是指我们要对哪些Joinpoint进行拦截的定义。
通过切入点表达式,可以精确地指定哪些方法需要被增强。
通知(Advice):
拦截到Joinpoint之后要做的事情就是通知。
通知分为前置通知、后置通知、异常通知、最终通知、环绕通知。
前置通知(Before Advice):在方法之前执行。
后置通知(After Advice):在方法之后执行。
环绕通知(Around Advice):在方法之前和之后执行,可以控制方法的执行。
异常通知(After-Throwing Advice):方法出现异常时执行。
最终通知(After-Returning Advice):在方法正常返回之后执行。
切面(Aspect):
一个关注点的模块化,这个关注点实现可能另外横切多个对象。
切面由切入点和通知共同组成,用于定义横切关注点的行为。
引入(Introduction):
引入是一种特殊的通知,可以在不修改类代码的前提下,为类动态地添加一些方法或属性。
目标对象(Target Object):
包含连接点的对象,也被称作被通知或被代理对象。
AOP代理(AOP Proxy):
AOP框架使用代理模式创建的对象,用于在连接点处插入通知(即应用切面)。
在Spring中,AOP代理可以用JDK代理或CGLIB代理实现。
织入(Weaving):
织入就是把一个advice应用到target的过程,是将切面增强逻辑应用到目标对象的连接点从而创建出AOP代理对象的过程。
织入可以在编译期、类装载期、运行期进行。
二、Spring AOP的底层实现
Spring中AOP代理由Spring的IOC容器负责生成和管理,其依赖关系也由IOC容器负责管理。因此,AOP代理可以直接使用容器中的其他Bean实例作为目标。Spring AOP的底层使用动态代理来实现:
JDK动态代理:如果代理对象实现了接口,则默认使用JDK动态代理来创建AOP代理。JDK动态代理只能对实现了接口的类生成代理,原理是通过在运行期间创建一个接口的实现类来完成对目标对象的代理。
CGLIB动态代理:如果代理对象没有实现接口,则Spring会切换使用CGLIB代理。CGLIB代理针对类进行代理,对是否实现接口无要求。原理是对指定的类生成一个子类,覆盖其中的方法。因为是继承,所以被代理的类最好不要声明为final类型。
三、动态代理的方式
JDK动态代理实现:
定义一个实现InvocationHandler接口的类。
通过构造函数或静态工厂方法等,注入被代理类。
实现invoke(Object proxy, Method method, Object[] args)方法。
在主函数中获得被代理类的类加载器。
使用Proxy.newProxyInstance(classLoader, interfaces, args)产生一个代理对象。
通过代理对象调用各种方法。
CGLIB动态代理实现:
定义一个实现了MethodInterceptor接口的类。
实现其intercept()方法,在其中调用proxy.invokeSuper()。
四、静态代理和动态代理的区别
五、应用场景
AOP的应用场景非常广泛,包括但不限于:
通过AOP,我们可以将这些横切关注点从业务逻辑代码中分离出来,使代码更加清晰、简洁、易于维护。在尚学堂百战程序员的学习中,掌握AOP面向切面编程对于提升编程能力和系统架构设计能力具有重要意义。