Spring中AOP的切点、通知和切点表达式源码分析
更新时间:2023-09-291. 切点
在AOP中,切点指的是需要被拦截的方法或一组方法的集合。Spring中的切点定义类是org.springframework.aop.Pointcut。Pointcut的核心职责是检查给定的类和方法是否符合拦截规则。Spring提供了多种Pointcut的实现,例如AspectJExpressionPointcut、AnnotationMatchingPointcut等。下面以AspectJExpressionPointcut为例,简单介绍一下切点的实现。
public class AspectJExpressionPointcut implements Pointcut, ClassFilter, MethodMatcher { // 切点表达式 private String expression; // ... public boolean matches(Class<?> targetClass) { if (this.pointcutExpression.matches(targetClass)) { // 符合切点表达式的类 return true; } // ... return false; } public boolean matches(Method method, Class<?> targetClass) { if (this.pointcutExpression.couldMatchJoinPointsInType(targetClass)) { AspectJExpressionPointcutShadowMatch shadowMatch = getShadowMatch(method, targetClass); if (shadowMatch.alwaysMatches()) { // 符合切点表达式的方法 return true; } // ... } // ... return false; } // ... }
2. 通知
在AOP中,通知是切面在特定的切点上要执行的逻辑。Spring中的通知定义类是org.springframework.aop.Advice。Advice接口是一个标记接口,表示一个切面的通知部分,Spring提供了多种实现,例如BeforeAdvice、AfterReturningAdvice等。下面以BeforeAdvice为例,简单介绍一下通知的实现。
public interface BeforeAdvice extends Advice { void before(Method method, Object[] args, Object target) throws Throwable; }
在调用目标方法之前,调用before方法执行切面的逻辑。其中,Method和args分别表示目标方法的反射对象和参数,target表示目标实例。开发人员可以实现BeforeAdvice接口自定义自己的Before通知逻辑。
3. 切点表达式
切点表达式是AOP中用来指定切点的语言,语法通常是一种特定的表达式语言。Spring中的AspectJExpressionPointcut是以AspectJ切点表达式为基础的实现。AspectJ是一个流行的AOP框架,它提供了灵活且强大的切点表达式语法,可以通过表达式来选择要拦截的方法。下面是一个简单的切点表达式示例:
execution(* com.example.service.*.*(..))
该表达式表示匹配com.example.service包中任意类的任意方法。在Spring中,我们可以通过在XML配置文件或注解中指定切点表达式来定义切点。
总结
Spring中的AOP提供了强大的切面编程功能,通过切点、通知和切点表达式的结合,我们可以精确地控制对目标方法的拦截。切点用于指定被拦截方法的选择,通知用于指定在特定切点上要执行的逻辑,而切点表达式则是指定切点的语言。Spring为我们提供了多种的切点和通知的实现,开发人员可以根据自己的需求自定义切点和通知。熟悉AOP的切点、通知和切点表达式的原理和使用方法,能够更好地开发和维护Spring应用。