博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
aop动态代理 事务 threadlocal
阅读量:4563 次
发布时间:2019-06-08

本文共 7551 字,大约阅读时间需要 25 分钟。

第一: package com.itheima.utils;import java.sql.Connection;import java.sql.SQLException;/** * 处理事务 的专门类    *                 也就是将这个事务处理的方面分离出来,形成一个独立的类 *  * 就是后面要说的方面代码 * @author wangli * */public class TransactionManager {    private static ThreadLocal
tL = new ThreadLocal
();//线程局部变量,用于放入Connection /** * 得到连接 * @return */ public static Connection getConnection(){ Connection con = tL.get();//从线程局部变量取出一个Connection ----第一次没有值 if(con==null){ //-第一次没有值 con = C3P0Util.getConneciton();//从连接池中取出一个连接 tL.set(con);//放入一个连接到线程局部变量中 } return con; } /** * 开启事务 * @throws Exception */ public static void startTransaction() throws Exception{ Connection con = getConnection(); con.setAutoCommit(false); } /** * 提交事务 * @throws Exception */ public static void commit() throws Exception{ Connection con = getConnection(); con.commit(); } /** * 回滚事务 * @throws Exception */ public static void rollback() throws Exception{ Connection con = getConnection(); con.rollback(); }}

第二:

package com.itheima.utils;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import javax.sql.DataSource;import com.mchange.v2.c3p0.ComboPooledDataSource;public class C3P0Util {    private static DataSource ds =new ComboPooledDataSource();            /**     * 用于得到数据源     * @return     */    public static DataSource getDataSource(){        return ds;    }        /**     * 用于从池中获取连接     * @return     */    public static synchronized Connection getConneciton(){        try {            return ds.getConnection();        } catch (SQLException e) {            e.printStackTrace();            throw new RuntimeException(e);        }    }        //关闭资源    public static void release(ResultSet rs,Statement st,Connection con ){        try {            if(rs!=null){                rs.close();                rs=null;//目的是让回收器立即进行垃圾回收            }        } catch (SQLException e) {            e.printStackTrace();        }                try {            if(st!=null){                st.close();                st=null;            }        } catch (SQLException e) {            e.printStackTrace();        }                try {            if(con!=null){                con.close();            }        } catch (SQLException e) {            e.printStackTrace();        }        }}

第三:

package com.itheima.utils;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import com.itheima.service.AccountService;import com.itheima.service.impl.AccountServiceImpl;public class BeanFactory {    /**     * 用于生成一个功能强磊的AccountService对象     * @return     */    public static  AccountService getBean(){        final AccountService as = new AccountServiceImpl();                //动态代理        AccountService asProxy = (AccountService)Proxy.newProxyInstance(as.getClass().getClassLoader(), as.getClass().getInterfaces(),new InvocationHandler() {            public Object invoke(Object proxy, Method method, Object[] args)                    throws Throwable {                if("transfor".equals(method.getName())){                    try {                        //横向加入代码                        TransactionManager.startTransaction();//开事务    前置通知                          //保证原有文法能执行                        Object obj=  method.invoke(as, args);                                                                                                TransactionManager.commit();//后置通知      //环绕通知:(前置通知  +后置通知)                        return obj;                    } catch (Exception e) {                        e.printStackTrace();                        try {                            TransactionManager.rollback();//异常通知                        } catch (Exception e1) {                            e1.printStackTrace();                        }                    }                    //finally中加入的代码:称为最终通知                                                        }                                return null;            }        });                return asProxy;    }}

第四:service

package com.itheima.service.impl;import com.itheima.dao.AccountDao;import com.itheima.dao.impl.AccountDaoImpl;import com.itheima.domain.Account;import com.itheima.service.AccountService;import com.itheima.utils.TransactionManager;/**AOP:Aspect Object Program   (面向切面编程   面向方面编程)        名词介绍:                就是将事物的某个方面功能代码抽取出去集中做实现,在需要系统需要用的时候,就将方面代码织入(加入)到系统中,从而实现功能扩展        它打破了原有纵向继承体系结构(代码复用),可以在关键时候横向织入方面代码(代码复用)                实现原理:              动态代理模式                      适合场景:事务控制  ,日志控制,权限管理,积分功能 * @author wangli * */public class AccountServiceImpl implements AccountService {    @Override    public void transfor(String sourceAcc, String targetAcc, float money) {                     AccountDao dao = new AccountDaoImpl();                //1.根据源账户名,得到一个账户对象                Account srcAcc = dao.getAccountByName(sourceAcc);//非常关键,目的是确保dao中用的是同一个Connection对象                //2.目标对象名,得到一 个目标账户                Account tarAcc = dao.getAccountByName(targetAcc);                //3.更新余额                srcAcc.setMoney(srcAcc.getMoney()-money);//源账户减                tarAcc.setMoney(tarAcc.getMoney()+money);//目标账户加                                //4.写入到表中                dao.updateAccount(srcAcc);                int i=1/0;                                dao.updateAccount(tarAcc);                                }        }

 

第五dao层

package com.itheima.dao.impl;import java.sql.Connection;import java.sql.SQLException;import org.apache.commons.dbutils.QueryRunner;import org.apache.commons.dbutils.handlers.BeanHandler;import com.itheima.dao.AccountDao;import com.itheima.domain.Account;import com.itheima.utils.TransactionManager;/** * */public class AccountDaoImpl implements AccountDao {    private QueryRunner qr = new QueryRunner();       @Override    public Account getAccountByName(String accountName) {        try {            Account acc = qr.query(TransactionManager.getConnection(),"select * from account where name=?", new BeanHandler
(Account.class),accountName); return acc; } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException(e); } } @Override public void updateAccount(Account acc) { try { qr.update(TransactionManager.getConnection(),"update account set money=? where name=?", acc.getMoney(),acc.getName()); } catch (SQLException e) { e.printStackTrace(); } } }

第六:测试

package com.itheima.test;import java.util.ArrayList;import java.util.List;import com.itheima.dao.AccountDao;import com.itheima.dao.impl.AccountDaoImpl;import com.itheima.domain.Account;import com.itheima.service.AccountService;import com.itheima.service.impl.AccountServiceImpl;import com.itheima.utils.BeanFactory;public class Client {    /**     * @param args     */    public static void main(String[] args) {        /*AccountDao dao = new AccountDaoImpl();        dao.transfor("aaa", "bbb",100);*/                        //2.        /*AccountService as = new AccountServiceImpl();        as.transfor("aaa", "bbb",100);*/                //3        AccountService as = BeanFactory.getBean();通过工厂创建对象,工厂里植入代理        as.transfor("aaa", "bbb",100);                            }}

 

转载于:https://www.cnblogs.com/baijin05/p/5076049.html

你可能感兴趣的文章
java8的一些用法
查看>>
(十)Hive分析窗口函数(二) NTILE,ROW_NUMBER,RANK,DENSE_RANK
查看>>
2018-11-19站立会议内容
查看>>
STM32 通用定时器相关寄存器
查看>>
【题解】1621. 未命名
查看>>
字符串加密算法
查看>>
Oracle的实例恢复解析
查看>>
UICollectionView cellForItemAt 不被调用
查看>>
巧用网盘托管私人Git项目
查看>>
python全栈脱产第19天------常用模块---shelve模块、xml模块、configparser模块、hashlib模块...
查看>>
[LeetCode] House Robber
查看>>
virtualbox中kali虚拟机安装增强功能
查看>>
java生成六位验证码
查看>>
iOS的MVP设计模式
查看>>
stringstream
查看>>
【转】HDU 6194 string string string (2017沈阳网赛-后缀数组)
查看>>
前后端分离
查看>>
存储过程
查看>>
福特F-550 4x4 越野房车设计方案欣赏_房车欣赏_21世纪房车网
查看>>
建立个长春互联网群
查看>>