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-> ...
随机推荐
- C++11新标准:decltype关键字
一.decltype意义 有时我们希望从表达式的类型推断出要定义的变量类型,但是不想用该表达式的值初始化变量(如果要初始化就用auto了).为了满足这一需求,C++11新标准引入了decltype类型 ...
- Notepad++ 代码格式化
在阅读别人的代码时偶尔会遇到格式很乱,阅读起来很费劲的情况,若手动改,很容易出错且很费时间,这时可以借助一些专业的编辑器来格式化代码,NotePad++是一个轻量级的代码编辑器,占用内存少,运行速度快 ...
- 编译安装log4cxx
1.介绍 Log4cxx是开放源代码项目Apache Logging Service的子项目之一,是Java社区著名的log4j的c++移植版,用于为C++程序提供日志功能,以便开发者对目标程序进行调 ...
- (multi)set的某些操作
(multi)set的某些操作 我们可以把multiset当作平衡树用~ 注意,必须定义小于运算符. s.begin() 返回指向第一个元素的迭代器. s.end() 返回指向最后元素的后面那个虚拟元 ...
- luogu1891 疯狂lcm ??欧拉反演?
link 给定正整数N,求LCM(1,N)+LCM(2,N)+...+LCM(N,N). 多组询问,1≤T≤300000,1≤N≤1000000 \(\sum_{i=1}^nlcm(i,n)\) \( ...
- JS的类型转换
首先我们要知道,在 JS 中类型转换只有三种情况,分别是: 转换为布尔值 转换为数字 转换为字符串 我们先来看一个类型转换表格 转Boolean 在条件判断时,除了 undefined, null, ...
- Boost lockfree deque 生产者与消费者多对多线程应用
boost库中有一个boost::lockfree::queue类型的 队列,对于一般的需要队列的程序,其效率都算不错的了,下面使用一个用例来说明. 程序是一个典型的生产者与消费者的关系,都可以使用多 ...
- [POI2009]KAM-Pebbles BZOJ1115 [ 待填坑 ] 博弈
有N堆石子,除了第一堆外,每堆石子个数都不少于前一堆的石子个数.两人轮流操作每次操作可以从一堆石子中移走任意多石子,但是要保证操作后仍然满足初始时的条件谁没有石子可移时输掉游戏.问先手是否必胜. 感谢 ...
- DRF教程7-token认证
Authentication 认证是将一个传入的请求和一组标识凭据相关联的机制,比如请求过来的用户,或者用户登录时携带的token. 然后权限策略就能使用这些凭据来决定是否允许这个请求. REST框架 ...
- Django 解答 01 (pycharm创建项目)
pycharm创建项目 1. 2. 3.Tools --->Deployment--->Options 这一条由always 改为 On explicit save action(Ctrl ...