Skip to content

混合切面类型 (Mixing Aspect Types)

在同一个配置中,完全可以混合使用通过自动代理支持实现的 @AspectJ 风格切面、基于 Schema 定义的 <aop:aspect> 切面、<aop:advisor> 声明的 Advisor,甚至还包括其他风格的代理和拦截器。所有这些都是基于相同的基础支撑机制实现的,可以毫无困难地共存。


补充教学

1. 为什么可以混合使用?

虽然 AOP 的声明方式(注解、XML、API)各不相同,但 Spring AOP 在底层实现上是高度统一的:

  • 统一的拦截器链:无论你用哪种方式定义的通知,Spring 最终都会将它们转化为统一的 Advisor 对象(包含一个 Pointcut 和一个 Advice)。
  • 责任链模式:最终执行时,所有匹配的通知都会被放入一个“拦截器链”中,按顺序依次执行。

2. 混合使用的典型场景

在现实的企业级项目中,混合使用非常常见:

  • 声明式事务:通常通过 XML 的 <tx:advice> 或注解的 @Transactional(本质是基础级 Advisor)来处理。
  • 业务监控:使用 @AspectJ 注解编写自定义切面,方便快捷。
  • 老代码集成:在一个已经存在大量 XML 配置的老项目中,新功能采用 @AspectJ 注解开发,两者可以完美融合。

3. 如何确保顺序?

当你混合使用不同的 AOP 风格时,排序(Ordering) 变得尤为重要:

  • 实现 Ordered 接口:这是最通用的方式。无论是 XML 定义的 Bean 还是标注了 @Aspect 的类,都可以实现此接口。
  • 使用 @Order 注解:适用于标注了 @Aspect 的类。
  • XML 属性:在 <aop:aspect><aop:advisor> 标签上直接设置 order 属性。

4. 配置建议

为了让各种风格协调工作,请注意以下几点:

  • 启用自动代理:确保你的配置中包含了 @EnableAspectJAutoProxy (Java) 或 <aop:aspectj-autoproxy /> (XML),这是让 @AspectJ 切面生效的前提。
  • 避免重复通知:如果一个切点同时被 XML 方案和 @AspectJ 方案匹配,该方法会被拦截两次。务必检查切入点表达式(Pointcut Expression),防止逻辑重叠。
  • 统一风格:虽然支持混合,但从可维护性角度考虑,建议团队对自定义业务切面规定一种统一的风格(通常首选 @AspectJ),仅在集成框架功能(如事务、缓存)时使用专用的配置风格。

Based on Spring Framework.