Spring中的@Pointcut切点详解

 更新时间:2023年08月02日 11:10:01   作者:路人丁.  
这篇文章主要介绍了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的实现

相关类结构:

image.png

抽象类主要定义了切点表达式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那么这个类就需要被代理,在方法调用时在具体判断方法是否需要事务。

image.png

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切点内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 如何实现广告弹窗触达频率的控制?

    如何实现广告弹窗触达频率的控制?

    这篇文章主要介绍了如何实现广告弹窗触达频率的控制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • Java基于IDEA实现http编程的示例代码

    Java基于IDEA实现http编程的示例代码

    这篇文章主要介绍了Java基于IDEA实现http编程的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • 深入解析Java多态进阶学习

    深入解析Java多态进阶学习

    java的动态绑定机制非常重要。这篇文章将带大家更深入的学习一下Java的多态,文中的示例代码讲解详细,对我们学习Java有一定帮助,需要的可以参考一下
    2022-07-07
  • Java设计模式系列之深入浅出单例模式

    Java设计模式系列之深入浅出单例模式

    设计模式是在大量的实践中总结和理论之后优选的代码结构,编程风格,以及解决问题的思考方式,下面这篇文章主要给大家介绍了关于Java设计模式系列之深入浅出单例模式的相关资料,需要的朋友可以参考下
    2021-09-09
  • java中使用数组进行模拟加密的方法

    java中使用数组进行模拟加密的方法

    这篇文章主要介绍了java中使用数组进行模拟加密的方法,需要的朋友可以参考下
    2014-08-08
  • 基于JDOM生成解析XML过程解析

    基于JDOM生成解析XML过程解析

    这篇文章主要介绍了基于JDOM生成解析XML过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • SpringBoot Bean花式注解方法示例下篇

    SpringBoot Bean花式注解方法示例下篇

    这篇文章主要介绍了SpringBoot Bean花式注解方法,很多时候我们需要根据不同的条件在容器中加载不同的Bean,或者根据不同的条件来选择是否在容器中加载某个Bean
    2023-02-02
  • Java实现Redis的集合(set)命令操作

    Java实现Redis的集合(set)命令操作

    这篇文章主要介绍了Java实现Redis的集合(set)命令操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • SpringBoot开发中的组件和容器详解

    SpringBoot开发中的组件和容器详解

    这篇文章主要介绍了SpringBoot开发中的组件和容器详解,SpringBoot 提供了一个内嵌的 Tomcat 容器作为默认的 Web 容器,同时还支持其他 Web 容器和应用服务器,需要的朋友可以参考下
    2023-09-09
  • 详解Spring框架下向异步线程传递HttpServletRequest参数的坑

    详解Spring框架下向异步线程传递HttpServletRequest参数的坑

    这篇文章主要介绍了详解Spring框架下向异步线程传递HttpServletRequest参数的坑,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-03-03

最新评论