Spring中的@Pointcut切点详解
作者:路人丁.
这篇文章主要介绍了Spring中的@Pointcut切点详解,pointcut就是切点,通知需要在哪些方法处进行增强,在AspectJ中用@Pointcut注解表达式标注,需要的朋友可以参考下
@Pointcut
pointcut就是切点,通知需要在哪些方法处进行增强,在AspectJ中用@Pointcut
注解表达式标注。
@Pointcut("execution(* com.aop.test.aspect..*.*(..))") public void pointcut() {}
在spring aop中定义了Pointcut接口规范,其中定义了类过滤器`ClassFilter`和方法匹配器`MethodMatcher`。
public interface Pointcut { ClassFilter getClassFilter(); MethodMatcher getMethodMatcher(); } // 类匹配 public interface ClassFilter { boolean matches(Class<?> clazz); } // 方法匹配 public interface MethodMatcher { // 方法是否匹配切点(静态匹配) boolean matches(Method method, Class<?> targetClass); // 代理对象已经创建,静态匹配成功(两个参数的matches) // 方法调用时检查三个参数的matches方法是否匹配 boolean isRuntime(); // 动态匹配,方法调用时带参数判断 boolean matches(Method method, Class<?> targetClass, Object... args); }
针对与AspectJ的实现
相关类结构:
抽象类主要定义了切点表达式expression
public abstract class AbstractExpressionPointcut implements ExpressionPointcut, Serializable { @Nullable private String location; @Nullable private String expression; } public class AspectJExpressionPointcut extends AbstractExpressionPointcut implements ClassFilter, IntroductionAwareMethodMatcher, BeanFactoryAware { private static final Set<PointcutPrimitive> SUPPORTED_PRIMITIVES = new HashSet<>(); static { SUPPORTED_PRIMITIVES.add(PointcutPrimitive.EXECUTION); SUPPORTED_PRIMITIVES.add(PointcutPrimitive.ARGS); SUPPORTED_PRIMITIVES.add(PointcutPrimitive.REFERENCE); SUPPORTED_PRIMITIVES.add(PointcutPrimitive.THIS); SUPPORTED_PRIMITIVES.add(PointcutPrimitive.TARGET); SUPPORTED_PRIMITIVES.add(PointcutPrimitive.WITHIN); SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_ANNOTATION); SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_WITHIN); SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_ARGS); SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_TARGET); } @Nullable private Class<?> pointcutDeclarationScope; private String[] pointcutParameterNames = new String[0]; private Class<?>[] pointcutParameterTypes = new Class<?>[0]; @Nullable private BeanFactory beanFactory; @Nullable private transient ClassLoader pointcutClassLoader; @Nullable private transient PointcutExpression pointcutExpression; private transient Map<Method, ShadowMatch> shadowMatchCache = new ConcurrentHashMap<>(32); }
AspectJExpressionPointcut的具体实现有兴趣在慢慢分析,其最主要的意图就是解析@Pointcut
注解表达式,调用ClassFilter#matches(Class)
和MethodMatcher#matches(Method, Class)
判断目标类及方法是否符合切点表达式的定义。
Spring事务如何实现的Pointcut
Spring事务也是通过AOP的方式来实现,那么事务必然也需要有其对应的切点匹配方式,这里我们讨论注解申明式事务@Transaction
,不难猜测这里的切点匹配就是判断目标类(及其方法)上是否有标记@Transaction
注解,类上或类中任意一个方法上标记了@Transaction
那么这个类就需要被代理,在方法调用时在具体判断方法是否需要事务。
public abstract class StaticMethodMatcherPointcut extends StaticMethodMatcher implements Pointcut { // 定义类过滤字段 private ClassFilter classFilter = ClassFilter.TRUE; } abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable { protected TransactionAttributeSourcePointcut() { setClassFilter(new TransactionAttributeSourceClassFilter()); } // 方法是否匹配 @Override public boolean matches(Method method, Class<?> targetClass) { TransactionAttributeSource tas = getTransactionAttributeSource(); return (tas == null || tas.getTransactionAttribute(method, targetClass) != null); } // 获取事务属性,交给子类实现 @Nullable protected abstract TransactionAttributeSource getTransactionAttributeSource(); // 内部类实现的类过滤器 private class TransactionAttributeSourceClassFilter implements ClassFilter { @Override public boolean matches(Class<?> clazz) { // 基础设施类忽略 if (TransactionalProxy.class.isAssignableFrom(clazz) || TransactionManager.class.isAssignableFrom(clazz) || PersistenceExceptionTranslator.class.isAssignableFrom(clazz)) { return false; } // 调用子类实现的获取事务属性 TransactionAttributeSource tas = getTransactionAttributeSource(); return (tas == null || tas.isCandidateClass(clazz)); } } }
在事务实现的Advisor中实现了具体的实现类
public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor { @Nullable private TransactionAttributeSource transactionAttributeSource; // 匿名内部类实现 private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() { @Nullable protected TransactionAttributeSource getTransactionAttributeSource() { return BeanFactoryTransactionAttributeSourceAdvisor.this.transactionAttributeSource; } }; }
这里可以看出在IOC容器中BeanFactoryTransactionAttributeSourceAdvisor
的bean中设置的TransactionAttributeSource
就是获取事务属性的具体工具类
到此这篇关于Spring中的@Pointcut切点详解的文章就介绍到这了,更多相关Spring的Pointcut切点内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!