Spring事务简略实现步骤

  1. 在事务配置类上申明@EnableTransactionManagement注解开启事务
  2. 在事务配置类上定义数据源
  3. 在事务配置类上定义事务管理器
  4. 在相干类或者办法上应用@Transactional申明事务

代码如下:

@Configuration@EnableTransactionManagementpublic class RootConfig{        @Bean    public DataSource dataSource(){        DruidDataSource dataSource = new DruidDataSource();        dataSource.setXXX();        ...                return dataSource;    }        @Bean    public PlatfromTransactionManager txManager(){        return new DataSourceTransactionManager(dataSource());    }}
@Servicepublic class UserService{    @Autowired    private UserRepository userRepository;        @Transactional    public void addUser(User user){        userRepository.save(user);    }}

@EnableTransactionManagement开启事务原理解析

@EnableTransactionManagement源码如下:

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Import(TransactionManagementConfigurationSelector.class)public @interface EnableTransactionManagement {    boolean proxyTargetClass() default false;    AdviceMode mode() default AdviceMode.PROXY;    int order() default Ordered.LOWEST_PRECEDENCE;}

能够看到,@EnableTransactionManagement接口类次要Import了TransactionManagementConfigurationSelector来实现其注入,而TransactionManagementConfigurationSelector又次要应用selectImport办法来实现其注入,代码如下:

@Overridepublic final String[] selectImports(AnnotationMetadata importingClassMetadata) {    Class<?> annoType = GenericTypeResolver.resolveTypeArgument(getClass(), AdviceModeImportSelector.class);    AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(importingClassMetadata, annoType);    if (attributes == null) {        throw new IllegalArgumentException(String.format(            "@%s is not present on importing class '%s' as expected",            annoType.getSimpleName(), importingClassMetadata.getClassName()));    }    AdviceMode adviceMode = attributes.getEnum(this.getAdviceModeAttributeName());    //依据AdviceMode返回不同的类型,默认是AdviceMode.PROXY。    String[] imports = selectImports(adviceMode);    if (imports == null) {        throw new IllegalArgumentException(String.format("Unknown AdviceMode: '%s'", adviceMode));    }    return imports;}@Overrideprotected String[] selectImports(AdviceMode adviceMode) {    switch (adviceMode) {        case PROXY:            return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};        case ASPECTJ:            return new String[] {TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};        default:            return null;    }}

其中次要性能点为依据AdviceMode抉择创立不同的bean,AdviceMode的默认代理形式是PROXY,jdk代理。所以返回的是AutoProxyRegistrar和ProxyTransactionManagementConfiguration。

咱们先剖析AutoProxyRegistrar,AutoProxyRegistrar实现了ImportBeanDefinitionRegistrar,那在创立bean的时候会调用registerBeanDefinitions办法。registerBeanDefinitions办法的实现:

@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {    boolean candidateFound = false;    Set<String> annoTypes = importingClassMetadata.getAnnotationTypes();    for (String annoType : annoTypes) {        AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annoType);        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;            //只有@EnableTransactionManagement注解才会走到这里            if (mode == AdviceMode.PROXY) {                AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);                if ((Boolean) proxyTargetClass) {                    AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);                    return;                }            }        }    }    //...}public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {    return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);}

能够看到,它通过注册InfrastructureAdvisorAutoProxyCreator来启动Spring Aop。

接下来再看ProxyTransactionManagementConfiguration的作用,代码如下:

@Configurationpublic class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {    @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)    public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {        BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();        advisor.setTransactionAttributeSource(transactionAttributeSource());        advisor.setAdvice(transactionInterceptor());        advisor.setOrder(this.enableTx.<Integer>getNumber("order"));        return advisor;    }    @Bean    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)    public TransactionAttributeSource transactionAttributeSource() {        return new AnnotationTransactionAttributeSource();    }    @Bean    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)    public TransactionInterceptor transactionInterceptor() {        TransactionInterceptor interceptor = new TransactionInterceptor();        interceptor.setTransactionAttributeSource(transactionAttributeSource());        if (this.txManager != null) {            interceptor.setTransactionManager(this.txManager);        }        return interceptor;    }}

ProxyTransactionManagementConfiguration是一个配置文件,注册了三个bean,BeanFactoryTransactionAttributeSourceAdvisor、AnnotationTransactionAttributeSource、TransactionInterceptor,而这三个类别离继承Advisor、Advice和Pointcut。即切面所需组件。

总结
@EnableTransactionManagement利用AutoProxyRegistrar启动Spring Aop,应用ProxyTransactionManagementConfiguration配置对应切面部件。