• aop动态代理 事务 threadlocal


    第一:
    package
    com.itheima.utils; import java.sql.Connection; import java.sql.SQLException; /** * 处理事务 的专门类 * 也就是将这个事务处理的方面分离出来,形成一个独立的类 * * 就是后面要说的方面代码 * @author wangli * */ public class TransactionManager { private static ThreadLocal<Connection> tL = new ThreadLocal<Connection>();//线程局部变量,用于放入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>(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);
            
            
            
        }
    
    }
  • 相关阅读:
    我是服务的执政官-服务发现和注册工具consul简介
    跳闸了啊! 服务容灾:熔断器简介
    论获取缓存值的正确姿势
    容器化redis高可用方案
    ASP.NET SessionState 解惑
    Thymeleaf 模板的使用
    记录js的一个图片预览功能代码
    记录一个简单的可以拖动的弹出层
    oracle安装报错[INS-30131]执行安装程序验证所需的初始设置失败(无法访问临时位置)解决方法!
    nginx学习笔记2
  • 原文地址:https://www.cnblogs.com/baijin05/p/5076049.html
Copyright © 2020-2023  润新知