All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.firefang.power.transaction.autoconfigure.TransactionAutoConfiguration Maven / Gradle / Ivy

There is a newer version: 0.0.6
Show newest version
package io.github.firefang.power.transaction.autoconfigure;

import java.util.Collections;

import javax.sql.DataSource;

import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
import org.springframework.transaction.interceptor.RollbackRuleAttribute;
import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
import org.springframework.transaction.interceptor.TransactionInterceptor;

import io.github.firefang.power.transaction.PowerTransactionProperties;

/**
 * Auto-configuration for transaction
 * 
 * @author xinufo
 *
 */
@Configuration
@EnableConfigurationProperties(PowerTransactionProperties.class)
@ConditionalOnBean(DataSource.class)
@AutoConfigureAfter({ DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class })
@ConditionalOnProperty(value = PowerTransactionProperties.SWITCH, matchIfMissing = true)
public class TransactionAutoConfiguration {
    private static final String TX_INTERCEPTOR_NAME = "powerTxInterceptor";
    private static final String[] DEFAULT_TX_BEAN_NAMES = { "*Service", "*ServiceImpl" };
    // @formatter:off
    private static final String[] DEFAULT_REQUIRED_METHOD_RULE_TX_ATTRIBUTES = {
            "add*",
            "save*",
            "insert*",
            "create*",
            "delete*",
            "remove*",
            "update*",
            "edit*",
            "batch*"
    };
    private static final String[] DEFAULT_READ_ONLY_METHOD_RULE_TX_ATTRIBUTES = {
            "select*",
            "find*",
            "count*",
            "list*",
            "query*",
            "get*",
            "check*",
            "*"
    };
    // @formatter:on

    private final PowerTransactionProperties properties;

    public TransactionAutoConfiguration(PowerTransactionProperties properties) {
        this.properties = properties;
    }

    @Bean(TX_INTERCEPTOR_NAME)
    public TransactionInterceptor powerTransactionInterceptor(PlatformTransactionManager manager) {
        NameMatchTransactionAttributeSource nta = new NameMatchTransactionAttributeSource();
        RuleBasedTransactionAttribute readOnly = readOnlyTransactionRule();
        RuleBasedTransactionAttribute required = transactionRule(TransactionDefinition.PROPAGATION_REQUIRED);

        // 默认配置
        for (String methodName : DEFAULT_READ_ONLY_METHOD_RULE_TX_ATTRIBUTES) {
            nta.addTransactionalMethod(methodName, readOnly);
        }
        for (String methodName : DEFAULT_REQUIRED_METHOD_RULE_TX_ATTRIBUTES) {
            nta.addTransactionalMethod(methodName, required);
        }

        // 自定义配置
        for (String methodName : properties.getReadOnlyTransactionAttributes()) {
            nta.addTransactionalMethod(methodName, readOnly);
        }
        for (String methodName : properties.getRequiredTransactionAttributes()) {
            nta.addTransactionalMethod(methodName, required);
        }
        return new TransactionInterceptor(manager, nta);
    }

    @Bean
    public BeanNameAutoProxyCreator transactionAutoProxy() {
        BeanNameAutoProxyCreator txAutoProxy = new BeanNameAutoProxyCreator();
        txAutoProxy.setInterceptorNames(TX_INTERCEPTOR_NAME);

        String[] customNames = properties.getTxBeanNames();
        if (customNames.length == 0) {
            txAutoProxy.setBeanNames(DEFAULT_TX_BEAN_NAMES);
        } else {
            String[] names = new String[DEFAULT_TX_BEAN_NAMES.length + customNames.length];
            System.arraycopy(DEFAULT_TX_BEAN_NAMES, 0, names, 0, DEFAULT_TX_BEAN_NAMES.length);
            System.arraycopy(customNames, 0, names, DEFAULT_TX_BEAN_NAMES.length, customNames.length);
            txAutoProxy.setBeanNames(names);
        }

        txAutoProxy.setProxyTargetClass(true);
        return txAutoProxy;
    }

    private RuleBasedTransactionAttribute readOnlyTransactionRule() {
        RuleBasedTransactionAttribute rta = new RuleBasedTransactionAttribute();
        rta.setReadOnly(true);
        return rta;
    }

    private RuleBasedTransactionAttribute transactionRule(int propagationBehavior) {
        RuleBasedTransactionAttribute rta = new RuleBasedTransactionAttribute();
        rta.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(Throwable.class)));
        rta.setPropagationBehavior(propagationBehavior);
        rta.setTimeout(TransactionDefinition.TIMEOUT_DEFAULT);
        rta.setIsolationLevel(Isolation.DEFAULT.value());
        return rta;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy