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);*/ //
AccountService as = BeanFactory.getBean();通过工厂创建对象,工厂里植入代理
as.transfor("aaa", "bbb",100); } }
aop动态代理 事务 threadlocal的更多相关文章
- Spring学习笔记之aop动态代理(3)
Spring学习笔记之aop动态代理(3) 1.0 静态代理模式的缺点: 1.在该系统中有多少的dao就的写多少的proxy,麻烦 2.如果目标接口有方法的改动,则proxy也需要改动. Person ...
- 技术的正宗与野路子 c#, AOP动态代理实现动态权限控制(一) 探索基于.NET下实现一句话木马之asmx篇 asp.net core 系列 9 环境(Development、Staging 、Production)
黄衫女子的武功似乎与周芷若乃是一路,飘忽灵动,变幻无方,但举手抬足之间却是正而不邪,如说周芷若形似鬼魅,那黄衫女子便是态拟神仙. 这段描写出自<倚天屠龙记>第三十八回. “九阴神抓”本是& ...
- spring AOP 动态代理和静态代理以及事务
AOP(Aspect Oriented Programming),即面向切面编程 AOP技术,它利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装 ...
- AOP动态代理解析1-标签的解析
spring.handlers http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespa ...
- Spring AOP动态代理原理与实现方式
AOP:面向切面.面向方面.面向接口是一种横切技术横切技术运用:1.事务管理: (1)数据库事务:(2)编程事务(3)声明事物:Spring AOP-->声明事物 2.日志处理:3.安全验证 ...
- Spring Aop 动态代理失效分析
1. Spring Aop 原理 Spring Aop 通过动态代理创建代理对象,在调用代理对象方法前后做增强. 2. Transactional, Async 注解失效? 当在动态代理方法中调用当前 ...
- String Aop 动态代理例子
动态代理原理:spring AOP采用动态代理来实现 (1)定义一个接口Boy package aop001; public interface Boy { public void beat(Stri ...
- Spring AOP 动态代理 缓存
Spring AOP应用:xml配置及注解实现. 动态代理:jdk.cglib.javassist 缓存应用:高速缓存提供程序ehcache,页面缓存,session缓存 项目地址:https://g ...
- AOP动态代理解析4-代理的创建
做完了增强器的获取后就可以进行代理的创建了 AnnotationAwareAspectJAutoProxyCreator->postProcessAfterInitialization-> ...
随机推荐
- Visual Studio 2012自动添加注释(如版权信息等)
http://blog.csdn.net/jiejiaozhufu/article/details/16357721注释宏的原码 /********************************** ...
- web 打印分页技巧
page-break-after 和 page-break-before: page-break-before和page-break-after CSS属性并不会修改网页在屏幕上的显示,这两个属性是 ...
- 关于执行memcached报错问题
执行#/usr/local/memcached/bin/memcached随后出现如下错误:./memcached: error while loading shared libraries: lib ...
- .NET 反射
反射是.NET很强大的一个机制. 它就像照妖镜一般的存在.它能调用你的任意私有成员,如:私有构造函数.私有方法.私有字段. 类的构造函数声明为了private,别人无法实例化对象出来?No,No,No ...
- Spark大数据处理 之 动手写WordCount
Spark是主流的大数据处理框架,具体有啥能耐,相信不需要多说.我们开门见山,直接动手写大数据界的HelloWorld:WordCount. 先上完整代码,看看咋样能入门. import org.ap ...
- P2156 [SDOI2009]细胞探索
$ \color{#0066ff}{ 题目描述 }$ 生物课上,老师开始为同学们介绍细胞.为了加深同学们的印象,老师在一张N×M的矩阵中定义了一种细胞,矩阵中仅有井号"#"和点&q ...
- throw new Error('Cyclic dependency' + nodeRep)
近日重装node_modules 依赖之后,项目启动报错 throw new Error('Cyclic dependency' + nodeRep) 查找资料后得知 产生这个 bug 的原因是循环引 ...
- HttpServletResponse 解决中文乱码
response.setHeader("Content-type", "text/html;charset=UTF-8"); response.setChara ...
- git commit 操作
查看提交历史 然后在此项目中运行 git log,应该会看到下面的输出: 合并commit 信息 我们需要将 2dfbc7e8 和 c4e858b5 合并成一个 commit,那么我们输入如下命令 ...
- ftp 添加用户及修改用户目录
添加用户 : useradd 用户名 -s /sbin/nologin //限定用户test不能telnet,只能ftp; usermod -s /sbin/bash 用户名 //用户恢复正常 ;该账 ...