一、spring事务源码
1. 注解
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(TransactionManagementConfigurationSelector.class) public @interface EnableTransactionManagement {
/** * 是否采用CGLIB进行代理 */ boolean proxyTargetClass() default false; /** * 使用代理模型JDK作为通知模型 */ AdviceMode mode() default AdviceMode.PROXY; /** * 优先级 */ int order() default Ordered.LOWEST_PRECEDENCE; }
2. 注册类
2.1 selectImports()
: 导入自动代理的配置对象,会注入 如果处理器已经存在,将根据以下优先级设置
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
/** * 根据通知模型返回相应的代理配置类型 */ @Override protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY: ////注册自动代理扫描 return new String[] {
AutoProxyRegistrar.class.getName(
)
,
//注入事务代理配置对象
ProxyTransactionManagementConfiguration
.
class
.
getName
(
)
}
;
case ASPECTJ
:
//返回 Aspectj代理对象方式
return
new
String
[
]
{
determineTransactionAspectClass
(
)
}
;
default
:
return
null
;
}
}
private
String
determineTransactionAspectClass
(
)
{
return
(
ClassUtils
.
isPresent
(
"javax.transaction.Transactional"
,
getClass
(
)
.
getClassLoader
(
)
)
?
TransactionManagementConfigUtils
.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME
:
TransactionManagementConfigUtils
.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME
)
;
}
}
2.2 registerOrEscalateApcAsRequired()
注入事务创建器,如果已经存在了代理创建器的话,会根据优先级进行注入;
private static BeanDefinition registerOrEscalateApcAsRequired(
Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
//首先判断是否有 org.springframework.aop.config.internalAutoProxyCreator bean
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
//获取到 org.springframework.aop.config.internalAutoProxyCreator
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
//判断类型是否跟当前注册的一样,如果不一样需要根据优先级进行设置
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
/** * 设置优先级,通过注解注入切面器的优先级最高,事务优先级最低,aop切面的最高 * InfrastructureAdvisorAutoProxyCreator * AspectJAwareAdvisorAutoProxyCreator * AnnotationAwareAspectJAutoProxyCreator */
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
//创建bean定义注册到容器中
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
3. 配置类
@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
/** * 创建增强器 */
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
TransactionAttributeSource transactionAttributeSource, TransactionInterceptor transactionInterceptor) {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
advisor.setTransactionAttributeSource(transactionAttributeSource);
advisor.setAdvice(transactionInterceptor);
if (this.enableTx != null) {
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
}
return advisor;
}
/** * 创建直接属性资源对象,其中主要的目的就是用于 Pointcut用来匹配方法注解 * 其中注解的匹配会根据依赖路径下面是否包含 javax.transaction.Transactional, javax.ejb.TransactionAttribute 来创建注解解析器 * 默认支持 SpringTransactionAnnotationParser解析器,用于匹配spring中的 @Transactional * SpringTransactionAnnotationParser、JtaTransactionAnnotationParser、Ejb3TransactionAnnotationParser */
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
return new AnnotationTransactionAttributeSource();
}
/** * 创建一个事务拦截器(Advice) * @param transactionAttributeSource * @return */
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionInterceptor transactionInterceptor(TransactionAttributeSource transactionAttributeSource) {
TransactionInterceptor interceptor = new TransactionInterceptor();
interceptor.setTransactionAttributeSource(transactionAttributeSource);
if (this.txManager != null) {
//设置事务管理器
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
}
}
当前抽象类实现了接口 这个接口会在 中注入一个名称 注册工厂,会返回 对象中的 属性,当前属性用于记录当前类是由谁进行导入的;
@Configuration
public abstract class AbstractTransactionManagementConfiguration implements ImportAware {
@Nullable
protected AnnotationAttributes enableTx;
@Nullable
protected TransactionManager txManager;
/** * 在 ConfigurationClassPostProcessor 中会注入一个 ImportAwareBeanPostProcessor 在bean创建完之后会处理 ImportAware的注解 * 获取到当前bean对象是由谁进行注入的元数据 */
@Override
public void setImportMetadata(AnnotationMetadata importMetadata) {
this.enableTx = AnnotationAttributes.fromMap(
importMetadata.getAnnotationAttributes(EnableTransactionManagement.class.getName()));
if (this.enableTx == null) {
throw new IllegalArgumentException(
"@EnableTransactionManagement is not present on importing class " + importMetadata.getClassName());
}
}
/** * 自动注入容器中 实现了 TransactionManagementConfigurer 可以用于获取事务管理器 */
@Autowired(required = false)
void setConfigurers(Collection<TransactionManagementConfigurer> configurers) {
if (CollectionUtils.isEmpty(configurers)) {
return;
}
if (configurers.size() > 1) {
throw new IllegalStateException("Only one TransactionManagementConfigurer may exist");
}
TransactionManagementConfigurer configurer = configurers.iterator().next();
this.txManager = configurer.annotationDrivenTransactionManager();
}
/** * 设置事务事件工厂,默认支持 TransactionalEventListener 注解的方法 * @return */
@Bean(name = TransactionManagementConfigUtils.TRANSACTIONAL_EVENT_LISTENER_FACTORY_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public static TransactionalEventListenerFactory transactionalEventListenerFactory() {
return new TransactionalEventListenerFactory();
}
}
4. Advisor
上面的配置类可以看到spring注入了一个 增强器,当前增强器中返回的比较重要的属性:
- advice: TransactionInterceptor;用于方法拦截的通知
- transactionAttributeSource:TransactionAttributeSource;用于匹配方法中是否有 @Transactional
- pointcut:TransactionAttributeSourcePointcut;抽象类,复写了getTransactionAttributeSource() 方法,并且返回 transactionAttributeSource属性
在aop的源码中我们看到,在spring找出所有 之后会调用其中 里面的 属性进行匹配,然后再调用 进行方法匹配。
spring先匹配类,创建 时,默认创建了 类型的过滤器;可以看到该类型是一个内部类,先匹配是否是一些基础类型,然后再通过上面复写的方法获取到 来进行匹配,配置类中注入的类型是
abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
protected TransactionAttributeSourcePointcut() {
setClassFilter(new TransactionAttributeSourceClassFilter());
}
}
-------------------------------------分割线--------------------------------------
/** * 通过Pointcut调用classFilter进行匹配时调用 */
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,由于上面已经复写了
TransactionAttributeSource tas = getTransactionAttributeSource();
return (tas == null || tas.isCandidateClass(clazz));
}
}
/** * org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#isCandidateClass * 其中遍历的 annotationParsers 是默认创建的注解解析器 * 默认会构建:SpringTransactionAnnotationParser */
public boolean isCandidateClass(Class<?> targetClass) {
for (TransactionAnnotationParser parser : this.annotationParsers) {
//当前判断的方法通过 AnnotationUtils.isCandidateClass(targetClass, Transactional.class); 进行匹配,只判断了一下注解类型和目标class的前缀,就返回了true
if (parser.isCandidateClass(targetClass)) {
return true;
}
}
return false;
}
看上面的依赖图能够发现 本身类就实现了 类型,获取方法匹配时默认就会返回本身,所以调用方法匹配时,会调用到自己的
abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
@Override
public boolean matches(Method method, Class<?> targetClass) {
TransactionAttributeSource tas = getTransactionAttributeSource();
// 调用AnnotationTransactionAttributeSource中的 getTransactionAttribute();但是 tas中并没有这个方法,当前方法在父类中 AbstractFallbackTransactionAttributeSource
return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}
}
public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
if (method.getDeclaringClass() == Object.class) {
return null;
}
//获取方法的缓存key对象
Object cacheKey = getCacheKey(method, targetClass);
//缓存中是否存在缓存的对象
TransactionAttribute cached = this.attributeCache.get(cacheKey);
if (cached != null) {
//获取到缓存后查看是否是默认的类型
if (cached == NULL_TRANSACTION_ATTRIBUTE) {
return null;
}
else {
return cached;
}
}
else {
//这里会通过方法去解析注解上面是否有 @Transactional 注解,并且把注解解析成 RuleBasedTransactionAttribute 对象进行返回
TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
if (txAttr == null) {
this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
}
else {
String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);
if (txAttr instanceof DefaultTransactionAttribute) {
DefaultTransactionAttribute dta = (DefaultTransactionAttribute) txAttr;
dta.setDescriptor(methodIdentification);
dta.resolveAttributeStrings(this.embeddedValueResolver);
}
if (logger.isTraceEnabled()) {
logger.trace("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
}
//存入缓存中
this.attributeCache.put(cacheKey, txAttr);
}
return txAttr;
}
}
protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}
//这里获取到最原始的方法;会判断方法是否是复写的方法,如果是复写的方法,获取到接口上的方法等。获取到方法后,会将方法进行缓存上
Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
//获取到方法中是否具有 @Transactional 注解,如果有注解,将注解中的属性解析成 RuleBasedTransactionAttribute 对象
TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
if (txAttr != null) {
return txAttr;
}
//如果方法上面获取不到 @Transactional 会尝试通过类进行获取
txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
//如果解析出的方法,跟传入的方法不一样,再尝试从原方法中获取
if (specificMethod != method) {
txAttr = findTransactionAttribute(method);
if (txAttr != null) {
return txAttr;
}
//再尝试从原方法定义的class中获取
txAttr = findTransactionAttribute(method.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
}
return null;
}
5. Advice
: 目标方法拦截器
public Object invoke(MethodInvocation invocation) throws Throwable {
//计算出目标类
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
//调用父类 TransactionAspectSupport 中的方法,并且设置一个回调方法,这个回调方法直接调用本体方法
return invokeWithinTransaction(invocation.getMethod(), targetClass, new CoroutinesInvocationCallback() {
@Override
@Nullable
public Object proceedWithInvocation() throws Throwable {
return invocation.proceed();
}
@Override
public Object getTarget() {
return invocation.getThis();
}
@Override
public Object[] getArguments() {
return invocation.getArguments();
}
});
}
5.1 invokeWithinTransaction()
protected Object invokeWithinTransaction(Method method