一、事务管理核心类及注解
1.1事务管理启动注解
/**
* 启用Spring注解驱动的事务管理功能,类似XML配置中的<tx:*>
* 应用在@Configuration注解的配置类上
* 配置传统的,命令式事务管理或者响应式事务管理
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
/**
* true:CGLIB
* false:JDK动态代理
* 注意两点:
* 1、该设置只会影响需要代理的类以何种方式被代理,但是不能完全决定。
* 2、这是一个全局的设置,将会影响所有spring管理需要被代理的bean。
*/
boolean proxyTargetClass() default false;
/**
* 表名事务通知应该怎么被应用。
* 默认值是AdviceMode.PROXY
* 代理模式只允许通过代理拦截调用
* 同一个类中的局部调用不会被拦截
* 本地调用中方法上的@Transactional注解将被忽略,因为Spring的拦截器不会在此类运行时场景中发挥作用
* 需要更高级的拦截模式,使用AdviceMode.ASPECTJ
*/
AdviceMode mode() default AdviceMode.PROXY;
/**
* 同一个连接点上多个通知时,事务advisor的执行顺序
*/
int order() default Ordered.LOWEST_PRECEDENCE;
}
1.2事务管理配置选择器
/**
* 根据@EnableTransactionManagement中的模式,选择AbstractTransactionManagementConfiguration的实现。
*/
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
/**
* PROXY:ProxyTransactionManagementConfiguration
* ASPECTJ:AspectJ(Jta)TransactionManagementConfiguration
*/
@Override
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
// 默认情况
case PROXY:
return new String[] {AutoProxyRegistrar.class.getName(),
ProxyTransactionManagementConfiguration.class.getName()};
case 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);
}
}
1.3自动代理创建器
/**
* 基于@EnableTransactionManagement中的proxyTargetClass和adviceMode配置
* 在BeanDefinitionRegistry上注册一个自动代理创建器
*/
public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
private final Log logger = LogFactory.getLog(getClass());
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean candidateFound = false;
Set<String> annTypes = importingClassMetadata.getAnnotationTypes();
for (String annType : annTypes) {
AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
if (candidate == null) {
continue;
}
Object mode = candidate.get("mode");
Object proxyTargetClass = candidate.get("proxyTargetClass");
if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() &&
Boolean.class == proxyTargetClass.getClass()) {
candidateFound = true;
if (mode == AdviceMode.PROXY) {
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
if ((Boolean) proxyTargetClass) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
return;
}
}
}
}
if (!candidateFound && logger.isInfoEnabled()) {
String name = getClass().getSimpleName();
logger.info(String.format("%s was imported but no annotations were found " +
"having both 'mode' and 'proxyTargetClass' attributes of type " +
"AdviceMode and boolean respectively. This means that auto proxy " +
"creator registration and configuration may not have occurred as " +
"intended, and components may not be proxied as expected. Check to " +
"ensure that %s has been @Import'ed on the same class where these " +
"annotations are declared; otherwise remove the import of %s " +
"altogether.", name, name, name));
}
}
}
1.4代理事务管理配置
/**
* 这个配置类配置了spring的一些基础设施bean,这些bean都是基于代理和注解驱动事务管理所需要的。
*/
@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
// advisor
@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;
}
// 注解事务属性源
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
return new AnnotationTransactionAttributeSource();
}
// advice
@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;
}
}
1.5@Transactional
/**
* 在独立的方法或者类上描述一个事务属性。
*
* 注解在类上,应用在该类及子类所有方法上。
* 不会向上应用到父类上;
* 继承的方法需要重新声明,才能参与到子类级别的注解应用中。
*
*
* 如果在此注解中没有配置自定义回滚规则,则事务将对RuntimeException和Error进行回滚,但不会对已检异常进行回滚。
*
* 回滚规则决定在抛出给定异常时是否应该回滚事务,这些规则是基于模式的。模式可以是一个完全限定类名,
* 也可以是一个异常类型的完全限定类名的子字符串(必须是Throwable的子类),目前不支持通配符。
*
* 回滚规则可以通过rollbackFor、noRollbackFor、rollbackForClassName、noRollbackForClassName配置,
* 它们允许将模式分别指定为Class引用或String。
*
* 有关此注解中其他属性语义的具体信息,参考:
* org.springframework.transaction.TransactionDefinition
* org.springframework.transaction.interceptor.TransactionAttribute
*
* 事务管理
*
* 该注解通常与由PlatformTransactionManager管理的线程绑定事务一起工作,将事务暴露给当前执行线程内的所有数据访问操作。
* 注意:这不会传播到方法内新启动的线程
*
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
@AliasFor("transactionManager")
String value() default "";
@AliasFor("value")
String transactionManager() default "";
String[] label() default {};
/**
* 事务传播类型。
* 默认是PROPAGATION_REQUIRED
*/
Propagation propagation() default Propagation.REQUIRED;
/**
* 事务隔离级别
* 默认值是Isolation.DEFAULT
*/
Isolation isolation() default Isolation.DEFAULT;
/**
* 事务超时时间
*/
int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
String timeoutString() default "";
/**
* 只读标志
*/
boolean readOnly() default false;
/**
* 定义0个或多个异常,它们必须是Throwable的子类,表示哪些异常类型必须导致事务回滚。
*/
Class<? extends Throwable>[] rollbackFor() default {};
String[] rollbackForClassName() default {};
/**
* 定义0个或多个异常,它们必须是hrowable的子类,表示哪些异常类型不进行事务回滚。
*/
Class<? extends Throwable>[] noRollbackFor() default {};
String[] noRollbackForClassName() default {};
}
二、bean注册
2.1配置类事务相关注解解析
- 实例化ConfigurationClassPostProcessor
- 在容器中找到AppConfig这个配置类(@Configuration)
- 解析配置类上的注解
- 解析@Import注解时发现TransactionManagementConfigurationSelector
- 通过选择器找到AutoProxyRegistrar和ProxyTransactionManagementConfiguration
- 将AutoProxyRegistrar添加到AppConfig的importBeanDefinitionRegistrars中
- ProxyTransactionManagementConfiguration作为配置类继续解析
- 自身构建为beanDefinition,将@Bean注解的三个bean解析出来,外加一个父类的@Bean
- 加载注册所有解析出来的bean定义信息(this.reader.loadBeanDefinitions(configClasses))
- loadBeanDefinitionsFromRegistrars通过AutoProxyRegistrar将internalAutoProxyCreator注册到容器
2.2bean注册结果
invokeBeanFactoryPostProcessors(beanFactory)新增11个bean定义信息:
- jdbcTemplate、transactionManager、dataSource由主配置类Appconfig中的@Bean解析而来。
- userService、userDaoImpl由组件扫描而来。
- @EnableTransactionManagement中@Import引入的TransactionManagementConfigurationSelector选择器返回了配置类ProxyTransactionManagementConfiguration和注册器AutoProxyRegistrar。
- AutoProxyRegistrar注册器注册了internalAutoProxyCreator。
- internalTransactionalEventListenerFactory是ProxyTransactionManagementConfiguration继承了AbstractTransactionManagementConfiguration,AbstractTransactionManagementConfiguration中的@Bean解析而来。
- internalTransactionAdvisor、transactionAttributeSource、transactionInterceptor是配置类ProxyTransactionManagementConfiguration中@Bean解析而来。
三、bean实例化
3.1实例化结果
registerBeanPostProcessors(beanFactory)后新增3个单例:
四、代理创建
4.1创建时机
- 单例(如:UserService)构建过程中,初始化bean时(initializeBean),BeanPostProcessor(InfrastructureAdvisorAutoProxyCreator)会被应用
// AbstractAutoProxyCreator
// InfrastructureAdvisorAutoProxyCreator继承AbstractAutoProxyCreator,实现BeanPostProcessor
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
4.2创建过程
- 查找所有的Advisor(当前容器中只有一个BeanFactoryTransactionAttributeSourceAdvisor)
- 查找符合条件的Advisor(目标类中有方法有@Transactional注解)
- 遍历目标类的所有方法
- 读取方法上@Transactional所有属性
- 解析所有属性,构建RuleBasedTransactionAttribute
- 遍历目标类的所有方法
- 代理工厂创建(ProxyFactory)
- 创建CGLIB AOP代理(ObjenesisCglibAopProxy)
- 获取callbacks(第一个还是DynamicAdvisedInterceptor[advised中的advisors中只有BeanFactoryTransactionAttributeSourceAdvisor])
- 创建代理类并实例化
- callbacks赋值(((Factory) proxyInstance).setCallbacks(callbacks))
- 创建完成
4.3代理对象创建核心源码
// AbstractAutoProxyCreator
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 查找能应用到bean上的Advice和Advisor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// AbstractAdvisorAutoProxyCreator
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 查找候选Advisor
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 查找符合条件的Advisor
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
// No need to iterate the methods if we're matching any method anyway...
return true;
}
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
Set<Class<?>> classes = new LinkedHashSet<>();
if (!Proxy.isProxyClass(targetClass)) {
classes.add(ClassUtils.getUserClass(targetClass));
}
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
for (Class<?> clazz : classes) {
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
// 遍历方法
for (Method method : methods) {
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
// methodMatcher是TransactionAttributeSourcePointcut
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
// TransactionAttrobuteSourcePointcut
public boolean matches(Method method, Class<?> targetClass) {
TransactionAttributeSource tas = getTransactionAttributeSource();
// getTransactionAttribute如果不为空说明该方法上有@Transactional,且属性值已经被解析好构建了规则对象
return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}
// CglibAopProxy
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
// 省略部分代码...
// 创建配置CGLIB Enhancer...
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
// 0号位 DynamicAdvisedInterceptor(BeanFactoryTransactionAttributeSourceAdvisor)
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
enhancer.setCallbackFilter(new