类分析: AspectJExpressionPointcut
AspectJExpressionPointcut
类实现了 Pointcut
、ClassFilter
和 MethodMatcher
接口,主要用于通过 AspectJ 表达式定义切入点。在 AOP 中,这种方式允许我们使用复杂的表达式来匹配类和方法,从而实现更灵活的切面逻辑。
类声明和字段
| public class AspectJExpressionPointcut implements Pointcut, ClassFilter, MethodMatcher { |
| |
| private static final Set<PointcutPrimitive> SUPPORTED_PRIMITIVES = new HashSet<PointcutPrimitive>(); |
| |
| static { |
| SUPPORTED_PRIMITIVES.add(PointcutPrimitive.EXECUTION); |
| } |
| |
| private final PointcutExpression pointcutExpression; |
- SUPPORTED_PRIMITIVES:这是一个静态集合,包含了该类支持的 AspectJ 切点原语。在这里,支持的原语是 EXECUTION,表示方法执行。
- pointcutExpression:这是解析后的切点表达式,用于匹配类和方法。
构造方法
| public AspectJExpressionPointcut(String expression) { |
| PointcutParser pointcutParser = PointcutParser.getPointcutParserSupportingSpecifiedPrimitivesAndUsingSpecifiedClassLoaderForResolution(SUPPORTED_PRIMITIVES, this.getClass().getClassLoader()); |
| pointcutExpression = pointcutParser.parsePointcutExpression(expression); |
| } |
- 构造方法接收一个 AspectJ 表达式字符串。
- PointcutParser 用于解析传入的表达式,支持指定的切点原语,并使用当前类加载器进行解析。
- 解析后的表达式保存在 pointcutExpression 字段中。
实现 ClassFilter 接口的方法
| @Override |
| public boolean matches(Class<?> clazz) { |
| return pointcutExpression.couldMatchJoinPointsInType(clazz); |
| } |
- 该方法用于判断给定的类是否与切点表达式匹配。
- pointcutExpression.couldMatchJoinPointsInType(clazz):返回一个布尔值,表示该类中的连接点是否可能与表达式匹配。
实现 MethodMatcher 接口的方法
| @Override |
| public boolean matches(Method method, Class<?> targetClass) { |
| return pointcutExpression.matchesMethodExecution(method).alwaysMatches(); |
| } |
- 该方法用于判断给定的方法是否与切点表达式匹配。
- pointcutExpression.matchesMethodExecution(method).alwaysMatches():返回一个布尔值,表示方法执行是否与表达式匹配。
实现 Pointcut 接口的方法
| @Override |
| public ClassFilter getClassFilter() { |
| return this; |
| } |
| |
| @Override |
| public MethodMatcher getMethodMatcher() { |
| return this; |
| } |
- 这两个方法返回当前对象,因为该类本身实现了 ClassFilter 和 MethodMatcher 接口。
整体流程
- 创建 AspectJExpressionPointcut 对象:
- 传入 AspectJ 表达式字符串,初始化 PointcutParser 并解析表达式,生成 pointcutExpression。
- 匹配类和方法:
- 使用 matches(Class<?> clazz) 方法匹配类。
- 使用 matches(Method method, Class<?> targetClass) 方法匹配方法。
- 返回自身:
- getClassFilter() 和 getMethodMatcher() 方法返回自身,方便在 AOP 框架中使用。
示例应用
假设你要创建一个 AspectJExpressionPointcut 实例,用于匹配所有 com.example.service 包中名称以 get 开头的方法:
| String expression = "execution(* com.example.service.*.get*(..))"; |
| AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(expression); |
总结
AspectJExpressionPointcut 是一个强大的工具,允许我们使用复杂的 AspectJ 表达式来定义切入点,灵活地匹配类和方法。这种方式在大型项目中尤其有用,因为它提供了比简单字符串匹配更强的表达能力,支持更复杂的切面逻辑。