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-> ...
随机推荐
- 跑实验配环境(tensorflow)
最近在学习用CNN(卷积神经网络)做图像质量评价,选择的论文是CVPR2014-Convolutional neural networks for no-reference image quality ...
- C#中的线程池使用(一)
1 线程池的概念 许多应用程序使用多个线程,但这些线程经常在休眠状态中耗费大量的时间来等待事件发生.其他线程可能进入休眠状态,并且仅定期被唤醒以轮询更改或更新状态信息,然后再次进入休眠状态.为了简化 ...
- 转:IDEA 与 eclipse 的部分区别!
Idea 与 Eclipse 快捷键的区别,上为Eclipse的快捷键,下为Idea的快捷键查找类名CTRL + SHIFT + RCTRL + N 查找JAR包中的类CTRL + SHIFT + T ...
- RPN(区域生成网络)
转:懒人元(侵删) RPN全称是Region Proposal Network,Region Proposal的中文意思是“区域选取”,也就是“提取候选框”的意思,所以RPN就是用来提取候选框的网络. ...
- 网络模拟工具Clumsy
Clumsy 是一款小巧而功能强大的开源弱网模拟工具,它能在windows平台下人工造成不稳定的网络状况,方便你调试应用程序在极端网络状况下的表现. 你可以选择 clumsy 提供的功能来有目的性的调 ...
- THINKPHP 框架的模板技术
//echo C('name'); App/Action/IndexAction.class.php文件夹下的 URL模式 //输出URL模式//echo C('URL_MODEL'),'<br ...
- python学习过程(四)
上节我们说了怎么从一个网页中获取所有的a标签,包括a标签的文本和a标签的url,以及最后经过整理,直接从网页中获取key-value键值对,也就是标签:url这种形式. 例如 : 百度: http:/ ...
- P4799 [CEOI2015 Day2]世界冰球锦标赛
\(\color{#0066ff}{题目描述}\) 今年的世界冰球锦标赛在捷克举行.Bobek 已经抵达布拉格,他不是任何团队的粉丝,也没有时间观念.他只是单纯的想去看几场比赛.如果他有足够的钱,他会 ...
- USACO 1.1.1 YOUR RIDE IS HERE
众所周知,在每一个彗星后都有一只UFO.这些UFO时常来收集地球上的忠诚支持者.不幸的是,他们的飞碟每次出行都只能带上一组支持者.因此,他们要用一种聪明的方案让这些小组提前知道谁会被彗星带走.他们为每 ...
- c#随笔-正则