☰
AOP 的七大术语是理解 Spring AOP 的基础
2026/10/8 14:25:44 网站建设 项目流程

AOP 的七大术语是理解 Spring AOP 的基础。这七个概念构成了 AOP 从“在哪里做”到“做什么”再到“怎么做到”的完整链条。

一、切面(Aspect)

切面是横切关注点的模块化。它是一个类,里面包含了切点和通知的定义。通俗说,切面就是“把哪些通用逻辑,应用到哪些方法上”的封装。

在 Spring 中,用@Aspect标注一个类,它就成为一个切面。

@Aspect@ComponentpublicclassLogAspect{@Pointcut("execution(* com.example.service.*.*(..))")publicvoidserviceLayer(){}@Around("serviceLayer()")publicObjectlog(ProceedingJoinPointpjp)throwsThrowable{System.out.println("开始执行:"+pjp.getSignature().getName());Objectresult=pjp.proceed();System.out.println("执行完成");returnresult;}}

LogAspect就是一个切面,它把“日志记录”这个横切关注点模块化了。

二、连接点(Join Point)

连接点是程序执行过程中可以插入切面的点。在 Spring AOP 中,连接点始终代表方法的执行。

一个类中的所有方法都可以是连接点。但并不是每个连接点都会被增强,具体哪些被增强由切点决定。

@ServicepublicclassUserService{publicvoidregister(Useruser){}// 这是一个连接点publicvoidupdate(Useruser){}// 这也是一个连接点publicUserfindById(Longid){}// 这也是一个连接点}

Spring AOP 只支持方法级别的连接点。AspectJ 还支持字段访问、构造器调用等更细粒度的连接点,但 Spring AOP 不支持。

三、切点(Pointcut)

切点是一组连接点的集合,用表达式定义“在哪些方法上织入通知”。切点决定了哪些连接点会被增强。

Spring AOP 使用 AspectJ 切点表达式语法。

@Pointcut("execution(* com.example.service.*.*(..))")publicvoidserviceLayer(){}

这个切点匹配com.example.service包下所有类的所有方法。

常见的切点表达式:

表达式含义
execution(* com.example.service.*.*(..))service 包下所有方法
execution(* com.example.service.UserService.*(..))UserService 类的所有方法
@annotation(com.example.annotation.Log)所有标注了 @Log 的方法
within(com.example.service.*)service 包下所有类
args(java.lang.String)参数为 String 的方法

切点是“筛选器”,从所有连接点中选出需要增强的那些。

四、通知(Advice)

通知是切面在切点上执行的具体动作,定义了“做什么”以及“什么时候做”。Spring AOP 提供了五种通知。

通知注解执行时机
前置通知@Before目标方法执行前
后置通知@After目标方法执行后(无论是否异常)
返回通知@AfterReturning目标方法正常返回后
异常通知@AfterThrowing目标方法抛出异常后
环绕通知@Around目标方法执行前后,最强大
@Before("serviceLayer()")publicvoidbefore(JoinPointjp){System.out.println("执行前:"+jp.getSignature().getName());}@AfterReturning(pointcut="serviceLayer()",returning="result")publicvoidafterReturning(JoinPointjp,Objectresult){System.out.println("返回:"+result);}@Around("serviceLayer()")publicObjectaround(ProceedingJoinPointpjp)throwsThrowable{longstart=System.currentTimeMillis();Objectresult=pjp.proceed();System.out.println("耗时:"+(System.currentTimeMillis()-start)+"ms");returnresult;}

@Around是功能最全的通知,可以控制目标方法是否执行、修改返回值、处理异常。

五、目标对象(Target)

目标对象是被切面增强的原始业务对象。它包含核心业务逻辑,不包含任何切面代码。

@ServicepublicclassUserService{publicvoidregister(Useruser){System.out.println("注册用户:"+user.getName());}}

UserService实例就是目标对象。Spring AOP 会为它生成代理对象,在代理对象中织入通知逻辑。

目标对象也叫“被通知对象”(Advised Object)。

六、代理(Proxy)

代理是织入通知后生成的对象。它包含了目标对象的业务逻辑,同时在方法调用前后插入了通知逻辑。客户端调用的是代理对象,而不是目标对象。

Spring AOP 使用两种代理:

  • JDK 动态代理:目标类实现了接口时使用,代理类实现同一接口。
  • CGLIB 代理:目标类没有接口时使用,代理类继承目标类。
// 从容器中获取的是代理对象UserServiceuserService=context.getBean(UserService.class);System.out.println(userService.getClass().getName());// 输出:com.sun.proxy.$Proxy12 或 UserService$$EnhancerBySpringCGLIB$$xxx

代理对象是 AOP 的实现载体。没有代理,通知就无法织入到目标方法上。

七、织入(Weaving)

织入是把切面应用到目标对象并创建代理对象的过程。它回答了“通知是怎么加到目标方法上的”。

织入可以在不同时机发生:

织入时机说明代表
编译期织入编译时修改字节码AspectJ 编译期织入
类加载期织入类加载时修改字节码AspectJ LTW
运行时织入运行时动态生成代理Spring AOP

Spring AOP 采用运行时织入:容器启动时,AbstractAutoProxyCreator在 Bean 初始化后判断是否需要代理,如果需要,就通过 JDK 或 CGLIB 生成代理对象,把通知逻辑织入。

// AbstractAutoProxyCreator.postProcessAfterInitialization()publicObjectpostProcessAfterInitialization(Objectbean,StringbeanName){if(bean!=null){ObjectcacheKey=getCacheKey(bean.getClass(),beanName);if(this.earlyProxyReferences.remove(cacheKey)!=bean){returnwrapIfNecessary(bean,beanName,cacheKey);}}returnbean;}

八、七大术语的关系

用一个流程串起来:

定义切面(Aspect) └── 切点(Pointcut)筛选出连接点(Join Point) └── 通知(Advice)定义增强逻辑 └── 织入(Weaving)到目标对象(Target) └── 生成代理(Proxy) └── 客户端调用代理,增强生效
术语英文一句话说明
切面Aspect横切关注点的模块化
连接点Join Point可以被拦截的方法执行点
切点Pointcut定义拦截哪些连接点
通知Advice拦截后执行的具体动作
目标对象Target被增强的原始业务对象
代理Proxy织入通知后生成的对象
织入Weaving把切面应用到目标对象的过程

九、总结

AOP 的七大术语描述了从“定义增强”到“应用增强”的完整过程:切面定义了横切逻辑,切点筛选出需要增强的方法,通知定义增强动作,织入把增强应用到目标对象上,生成代理对象,客户端调用代理时增强生效。理解这七个术语,就理解了 Spring AOP 的工作原理。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询