手动实现IOC与事务控制-基于JDBC-2-动态代理改造Service事务

手动实现IOC与事务控制-基于JDBC
https://blog.csdn.net/ko0491/article/details/106939211
之前实现了,IOC与事务,但是在Service中有很大一段try-catch代理,事务代码与业务代码混合在一起
在这里插入图片描述

使用动态代理改造Service

对所有的Service使用动态代理
在这里插入图片描述
思路:
在Servlet中不再直接调用ServiceImpl,而是调用了使用动态代理增加了事务控制后的代理对象

  • 创建动态代理工厂

package com.liu.spring.proxy.transaction;

import com.liu.spring.transaction.TransactionManager;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @Description 事务代理工厂
 * @ClassName TransactionProxyFactory
 * @Author 刘楠
 * @date 2020.06.24
 */
public class TransactionProxyFactory {

    private TransactionProxyFactory(){

    }
    private static  TransactionProxyFactory transactionProxyFactory = new TransactionProxyFactory();

    public static  TransactionProxyFactory getInstance(){

        return transactionProxyFactory;

    }

    public Object getJdkProxy(Object obj){

        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                obj.getClass().getInterfaces(), new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("开始使用jdk动态代理...");
                        Object result=null;
                        try {

                            TransactionManager.getInstance().beginTransaction();
                             result = method.invoke(obj, args);
                            TransactionManager.getInstance().commitTransaction();
                        }catch (Exception e){
                            e.printStackTrace();
                            //使用事务管理器回滚事务
                            TransactionManager.getInstance().rollbackTransaction();
                            //抛出异常 便于上层 捕获
                            throw  new RuntimeException(e);
                        }
                        System.out.println("使用jdk动态代理结束...");
                        return result;

                    }
                });
    }

    public Object getCglibProxy(Object object){

        return Enhancer.create(object.getClass(), new MethodInterceptor() {
            @Override
            public Object intercept(Object proxyObject, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                System.out.println("开始使用cgLib动态代理...");
                Object result=null;
                try {

                    TransactionManager.getInstance().beginTransaction();
                    result = method.invoke(object, args);
                    TransactionManager.getInstance().commitTransaction();
                }catch (Exception e){
                    e.printStackTrace();
                    //使用事务管理器回滚事务
                    TransactionManager.getInstance().rollbackTransaction();
                    //抛出异常 便于上层 捕获
                    throw  new RuntimeException(e);
                }
                System.out.println("使用cgLib动态代理结果...");
                return result;
            }
        });
    }


}

改造service 去掉事务控制代码


package com.liu.spring.service.impl;

import com.liu.spring.dao.AccountDao;
import com.liu.spring.dao.impl.AccountDaoImpl;
import com.liu.spring.entity.Account;
import com.liu.spring.factory.BeanFactory;
import com.liu.spring.service.TransferService;
import com.liu.spring.transaction.TransactionManager;
import com.liu.spring.util.ConnectionUtils;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.SQLException;

/**
 * @Description
 * @ClassName TransferServcieImpl
 * @Author 刘楠
 * @date 2020.06.23
 */
public class TransferServcieImpl implements TransferService {

//   private AccountDao accountDao = new AccountDaoImpl();

    private AccountDao accountDao ;




    @Override
    public boolean transfer(String fromAccount, String toAccount, Integer money) throws Exception {
        System.out.println("=====开始转账==== ");



        try {
            /**
             * 开启事务关闭事务的自动提交
             */
//            ConnectionUtils.getInstance().getCurrentConnection().setAutoCommit(false);
            //使用事务管理器-开启使用
            //TransactionManager.getInstance().beginTransaction();
            Account fAccount = accountDao.queryByCardNo(fromAccount);
            Account tAccount = accountDao.queryByCardNo(toAccount);

            fAccount.setMoney(fAccount.getMoney()-money);
            tAccount.setMoney(tAccount.getMoney()+money);
            accountDao.updateAccountByCardno(fAccount);
//            int i=1/0;
            accountDao.updateAccountByCardno(tAccount);
            /**
             * 正常执行完成 提交事务
             */
//            ConnectionUtils.getInstance().getCurrentConnection().commit();
            //使用事务管理器-提交事务
            //TransactionManager.getInstance().commitTransaction();
        }catch (Exception e){
            e.printStackTrace();
            /**
             * 有异常回滚事务
             */
//            ConnectionUtils.getInstance().getCurrentConnection().rollback();
            //使用事务管理器回滚事务
            //TransactionManager.getInstance().rollbackTransaction();
            //抛出异常 便于上层 捕获
            throw  new RuntimeException(e);
        }

        return true;
    }

    /**
     * 提供get,set方法
     * @return
     */
    public AccountDao getAccountDao() {
        return accountDao;
    }

    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }
}

改造Servelt

@WebServlet(name = "transferServlet",urlPatterns = "/transferServlet")
public class TransferServlet extends HttpServlet {
    /**
     * http mine,json类型
     */
    public static final String MIME_TYPE_JSON = "application/json";
    /**
     * http mine,json类型指定utf-8编码
     */
    public final static String MIME_TYPE_JSON_UTF8 = MIME_TYPE_JSON + ";charset=UTF-8";
    //1.实例化TransferService
//    private TransferService transferService = new TransferServcieImpl();
//    private TransferService transferService =(TransferService) BeanFactory.getBean("transferService");
    //从代理工厂获取增加了事务功能的对象
    private TransferService transferService=(TransferService) TransactionProxyFactory.getInstance()
                                .getJdkProxy(BeanFactory.getBean("transferService"));
....
}

测试正常

在这里插入图片描述

发起测试
在这里插入图片描述
在这里插入图片描述

开始使用jdk动态代理…
=开始转账
queryByCardNo connection com.mysql.jdbc.JDBC4Connection@7c60e05f
queryByCardNo connection com.mysql.jdbc.JDBC4Connection@7c60e05f
updateAccountByCardno connection com.mysql.jdbc.JDBC4Connection@7c60e05f
updateAccountByCardno connection com.mysql.jdbc.JDBC4Connection@7c60e05f
使用jdk动态代理结束…

打开异常代码

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
没有成功事务控制成功
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章