AOP的一般定义:
AOP是一种编程范式,用于将关注点(concerns)从应用程序的主要业务逻辑中解耦。
关注点是指在应用程序中横切多个模块或组件的功能,而不是特定于一个模块的功能。
AOP通过将这些关注点封装成切面(aspects)来实现,切面是由通知(advice)和切点(pointcut)组成的。
通知是在切点上执行的代码块,通常包括前置通知(before advice)、后置通知(after advice)、环绕通知(around advice)等。
切点是在应用程序中选择何处执行通知的规则或条件。
AOP可以提供更好的模块化、可维护性和可重用性,因为关注点的逻辑被集中管理,而不是分散在整个应用程序中。
在Java中,AOP通常使用框架来实现,如Spring Framework的AOP模块,它提供了一种方便的方式来定义切面、通知和切点,并将它们应用到应用程序中的组件上。通过使用AOP,开发人员可以更容易地处理横切关注点,从而改善代码的结构和可维护性。
1.Pointcut 切点
概念
Spring 的切入点(pointcut)模型使切入点重用独立于通知类型。 您可以使用相同的切点来定位不同的通知(advice)。
org.springframework.aop.Pointcut 接口是中心接口,用于将advice定位到特定的类和方法。 完整接口如下:
public interface Pointcut {
ClassFilter getClassFilter();
MethodMatcher getMethodMatcher();
}
将切入点接口分为两部分,允许重用类和方法匹配部分以及细粒度组合操作(例如与另一个方法匹配器执行“联合”)。
ClassFilter 接口用于将切入点限制为一组给定的目标类。 如果 matches() 方法始终返回 true,则所有目标类都匹配。 以下代码显示了 ClassFilter 接口定义:
public interface ClassFilter {
boolean matches(Class clazz);
}
MethodMatcher 接口定义:
public interface MethodMatcher {
boolean matches(Method m, Class targetClass);
boolean isRuntime();
boolean matches(Method m, Class targetClass, Object[] args);
}
在上面的matches(Method, Class) 方法用于匹配这个切入点是否与目标类上的给定方法匹配。 可以在创建 AOP 代理时执行此匹配,以避免对每个方法调用进行测试。 如果二参数 matches 方法对于给定方法返回 true,并且 MethodMatcher 的 isRuntime() 方法返回 true,则在每次方法调用时都会调用三参数 matches 方法。 这使得切入点可以在目标建议开始之前立即查看传递给方法调用的参数。
大多数 MethodMatcher 实现都是静态的,这意味着它们的 isRuntime() 方法返回 false。 在这种情况下,永远不会调用三参数 matches 方法。
如果可能,尝试将切入点静态化,允许 AOP 框架在创建 AOP 代理时缓存切入点评估的结果。
切入点的操作
Spring 支持切入点上的操作(并集和交集)。
Union 并集表示任一切入点匹配的方法。
intersection 交集意味着两个切入点都匹配的方法。
Union 通常更有用。 您可以使用 org.springframework.aop.support.Pointcuts 类中的静态方法或使用同一包中的 ComposablePointcut 类来组合切入点。 然而,使用 AspectJ 切入点表达式通常是一种更简单的方法。
2.Spring 中的通知 API
advice通知的生命周期
每个advice都是一个 Spring bean。 advice实例可以在所有advice对象之间共享,也可以对于每个advice对象是唯一的。 这对应于每个类或每个实例的advice。
最常使用的是每个类通知。 它适用于一般advice,例如事务。 这些不依赖于代理对象的状态或添加新状态。 他们只是按照方法和参数执行。
每个实例的advice适合介绍,以支持 mixin。 在这种情况下,建议将状态添加到代理对象。
您可以在同一个 AOP 代理中混合使用共享建议和每个实例advice。