手写@EnableTransactionalManagement

  • 定义一个注解,用于标注于方法上,标志着此方法是一个事务方法。
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTransaction {
    

}
  • 定义一个开启事务功能的注解
@Component
@Import(TransActionBeanPostProcessor.class)
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EnableTransactionalManagement {
}
  • BeanPostProcessor Bean的后置处理器,拦截每一个创建后的对象,这里拦截的是Bean的方法上标注了MyTransaction 注解的对象,为其创建代理对象。
/**
    对象事务处理器
 */
public class TransActionBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        //判断bean的类或者方法上是否标注了事务注解@MyTransaction
        MyTransaction annotation = AnnotationUtils.findAnnotation(bean.getClass(), MyTransaction.class);
        boolean isTxProxy = false;
        if (annotation == null){
            //从方法上寻找
            Method[] methods = bean.getClass().getMethods();
            for (Method method : methods) {
                annotation = AnnotationUtils.findAnnotation(method, MyTransaction.class);
                if (annotation != null){
                    isTxProxy = true;
                    break;
                }
            }
        }

        if (isTxProxy){
            //为Bean创建代理对象
            bean = TransactionProxyUtil.getTxProxyObject(bean, transactionManagement());
        }

        return bean;
    }

    //给容器中注入事务管理器
    @Bean
    public PlatformTransactionManagement transactionManagement(){
        return new PlatformTransactionManagement();
    }

}

  • JdbcTransactionStatus 定义一个事务的状态信息
public class JdbcTransactionStatus implements TransactionStatus{

    //private DataSource dataSource;

    private Connection connection;

    @Override
    public void start() {
        //connection.setAutoCommit(false);
        System.out.println("connection.setAutoCommit(false); 开启事务");

    }

    @Override
    public void commit() {
        //事务提交
        //connection.commit();
        System.out.println("事务提交了...");
    }

    @Override
    public void rollback() {
        try {
            //事务回滚
            //connection.rollback();
            System.out.println("事务回滚了...");
        } catch (Exception throwables) {
            throwables.printStackTrace();
        }
    }

    @Override
    public void close() {
        //connection.close();
        System.out.println("事务连接关闭了...");
    }
}
  • PlatformTransactionManagement 定义平台事务管理器,这个事务管理器主要管理DataSource数据源,在开启事务之前将Connection和当前线程绑定。
public class PlatformTransactionManagement implements TransactionManagement{

    @Override
    public TransactionStatus getTransaction() {
        return new JdbcTransactionStatus();
    }

    @Override
    public void commit(TransactionStatus status) {
        status.commit();
    }

    @Override
    public void rollback(TransactionStatus status) {
        status.rollback();
    }

    @Override
    public void close(TransactionStatus status) {
        status.close();
    }

}
/**
    事务管理器
 */
public interface TransactionManagement {

    //获取一个事务
    TransactionStatus getTransaction();

    //提交事务
    void commit(TransactionStatus status);

    //回滚事务
    void rollback(TransactionStatus status);

    //关闭连接
    void close(TransactionStatus transaction);
}

/**
    事务状态定义
 */
public interface TransactionStatus {

    void start();

    //提交
    void commit();

    //回滚
    void rollback();

    //关闭连接
    void close();
}
  • 定义事务代理逻辑,创建代理对象,栏目目标方法,反射执行真正的方法,这里使用的是JDK的动态代理实现的。
public class TransactionProxyUtil {

    public static Object getTxProxyObject(Object source,TransactionManagement transactionManagement){

        Object proxyInstance = Proxy.newProxyInstance(source.getClass().getClassLoader(), source.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //将方法替换为实现类中的方法,否则获取不到实现类方法上标注的注解
                        String name = method.getName();
                        Class<?>[] parameterTypes = method.getParameterTypes();
                        method = source.getClass().getMethod(name,parameterTypes);
                        Object result = null;
                        if (!method.isAnnotationPresent(MyTransaction.class)){
                            result = method.invoke(source,args);
                        }else {
                            //获取切面类,封装方法
                            //开启事务
                            TransactionStatus transaction = transactionManagement.getTransaction();
                            transaction.start();
                            try {
                                result = method.invoke(source,args);
                                transactionManagement.commit(transaction);
                            }catch (Throwable e){
                                transactionManagement.rollback(transaction);
                            }finally {
                                transactionManagement.close(transaction);
                            }
                        }
                        return result;
                    }
                });
        return proxyInstance;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值