创作内容丰富的干货文章很费心力,感谢点过此文章的读者,点一个关注鼓励一下作者,激励他分享更多的精彩好文,谢谢大家!
二大核心模式
Spring事务架构 ,用到了二大核心模式。
模式一: 策略模式
设计了统一的事务管理器超级接口, PlatformTransactionManager 是 Spring事务管理器设计的 基类。
PlatformTransactionManager 基类,实现了事务执行设计到的三个核心方法:
不同的 数据管理组件JDBC、Hibernate等,为Spring都提供了对应的事务管理器 实现类。
既然是策略模式, 如何进行动态的决策呢?
在动态代理模式的切面的支撑类 TransactionAspectSupport 中, 会有一个 determineTransactionManager 方法,动态的从IOC容器,加载注册了的 PlatformTransactionManager 实现类。上图中的脚手架,用到的orm框架是 jpa。在spring的bean factory里边注册了的PlatformTransactionManager 实现类是 JpaTransactionManager。
所以,这里的 JpaTransactionManager 作为事务管理器。
模式二: 动态代理模式
动态代理有JDK的动态代理、 Aspectj的动态代理,SpringAOP动态代理 ,很多种。
SpringAOP 和 Aspectj的动态代理有何联系呢? 本质上 Aspectj是一种静态代理,而SpringAOP是动态代理。但Aspectj的一套定义AOP的API非常好,直观易用。
但是,AOP联盟的关键词有Advice(顶级的通知类/拦截器)、MethodInvocation(方法连接点)、
MethodInterceptor(方法拦截器)
SpringAOP与AOP联盟关系
SpringAOP在AOP联盟基础上又增加了几个类,丰富了AOP定义及使用概念,SpringAOP 的核心名称和概念包括:
- Advisor:包含通知(拦截器),Spring内部使用的AOP顶级接口,还需要包含一个aop适用判断的过滤器,考虑到通用性,过滤规则由其子接口定义,例如IntroductionAdvisor和 PointcutAdvisor,过滤器用于判断bean是否需要被代理
- Pointcut: 切点,属于过滤器的一种实现,匹配过滤哪些类哪些方法需要被切面处理,包含一个ClassFilter和一个MethodMatcher,使用PointcutAdvisor定义时需要
- ClassFilter:限制切入点或引入点与给定目标类集的匹配的筛选器,属于过滤器的一种实现。过滤筛选合适的类,有些类不需要被处理
- MethodMatcher:方法匹配器,定义方法匹配规则,属于过滤器的一种实现,哪些方法需要使用AOP
SpringAOP实现的大致思路:
- 配置获取Advisor (顾问):拦截器+AOP匹配过滤器,生成Advisor
- 生成代理:根据Advisor生成代理对象,会生成JdkDynamicAopProxy或CglibAopProxy
- 执行代理:代理类执行代理时,从Advisor取出拦截器,生成MethodInvocation(连接点)并执行代理过程。
Advisor 是用于定义切面的对象,它包含了切点和通知两个部分。
- 切点指定了哪些方法需要被拦截 , 使用@Pointcut 注解
- 通知则指定了拦截后需要执行的逻辑。
Interceptor 是用于拦截后,执行拦截逻辑的对象,它实现了 Spring 的 MethodInterceptor 接口,负责拦截方法的执行,并在方法执行前后执行一些操作。
下面是一个使用 Advisor 和 Interceptor 的示例:
@Aspect
@Component
public class MyInterceptor {
//切点
@Pointcut("execution(* com.example.service.*.*(..))")
public void pointcut() {}
@Around("pointcut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
// 在方法执行前执行的逻辑
System.out.println("before method");
// 执行被拦截的方法
Object result = pjp.proceed();
// 在方法执行后执行的逻辑
System.out.println("after method");
return result;
}
}
在上面的代码中,我们使用了 Advisor 和 Interceptor 来实现对 com.example.service 包中所有方法的拦截。
首先,我们定义了一个切点 pointcut(),它指定了需要拦截的方法。
然后,我们定义了一个 around() 方法,并使用 @Around 注解将它与切点关联起来。在 around() 方法中,我们实现了拦截逻辑,即在方法执行前后分别输出 "before method" 和 "after method"。最后, 我们通过 pjp.proceed() 方法执行了被拦截的方法,并返回了它的执行结果。
需要注意的是,为了让 Spring 能够识别 MyInterceptor 类并将它作为 Advisor 使用,我们需要在它上面加上 @Aspect 和 @Component 注解。
注意 Advisor 是动态生成的,但是Spring也会实现了一个类似于 PointcutAdvisor 的接口,可以根
据配置的切入点和目标方法生成代理对象,调用咱们定义的MyInterceptor 实现拦截和AOP增强功能。