使用DBUtils、动态代理以及注解实现事务控制
来源:互联网 发布:淘宝网流量分析 编辑:程序博客网 时间:2024/05/29 09:19
主要思路:
- 使用ThreadLoacal来传递Connection
- 使用动态代理来增强service层的方法,对于CUD方法添加事务
- 通过注解+反射来扫描方法是否开启事务
代码
C3P0工具类
package com.fly.utils;import java.sql.Connection;import java.sql.SQLException;import javax.sql.DataSource;import com.mchange.v2.c3p0.ComboPooledDataSource;public class C3P0Utils { private static ComboPooledDataSource dataSource = new ComboPooledDataSource(); private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>(); public static DataSource getDataSource() { return dataSource; } public static Connection getConnnection() throws SQLException { Connection conn = threadLocal.get(); if(conn==null){ conn = dataSource.getConnection(); threadLocal.set(conn); } return conn; } public static void closeConnection() throws SQLException { Connection conn = threadLocal.get(); if(conn != null){ conn.setAutoCommit(true); conn.close(); threadLocal.remove(); } } public static void beginTransaction() throws SQLException { Connection connnection = getConnnection(); connnection.setAutoCommit(false); } public static void commitTransaction() throws SQLException { Connection connnection = getConnnection(); connnection.commit(); } public static void rollbackTransaction() throws SQLException { Connection connnection = getConnnection(); connnection.rollback(); }}
Transaction注解
package com.fly.utils.annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Inherited;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * Transaction注解 * 该注解用于方法 * 如果方法上有该注解,则此方法会开启事务 * (注意,需要在该方法所在的类上添加AOP注解) */@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Inheritedpublic @interface Transaction {}
AOP注解
package com.fly.utils.annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Inherited;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * AOP注解 * 用于类的注解, * 增加此注解后,用工厂生成bean时会自动为该对象增加一个代理对象, * 该代理对象可以对内部的方法进行注解扫描, * 如果方法含有注解@Transaction,则开启事务操作。 */@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Inheritedpublic @interface AOP {}
动态代理的切面InvocationHandlerImpl
package com.fly.utils.aop;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import com.fly.utils.C3P0Utils;import com.fly.utils.annotation.Transaction;/** * 用于实现事务控制 */public class InvocationHandlerImpl implements InvocationHandler { private Object target; public InvocationHandlerImpl() { } public InvocationHandlerImpl(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Exception { Object returnValue = null; //是否开启事务注解 boolean isTransaction = method.isAnnotationPresent(Transaction.class); if (!isTransaction) { //如果未开启了事务 System.out.println("未开启事务"); System.out.println(method.getName()); returnValue = method.invoke(target, args); return returnValue; } //如果开启事务 System.out.println("开启了事务"); System.out.println(method.getName()); try { C3P0Utils.beginTransaction(); returnValue = method.invoke(target, args); C3P0Utils.commitTransaction(); } catch (Exception e) { C3P0Utils.rollbackTransaction(); throw e; } finally { C3P0Utils.closeConnection(); } return returnValue; }}
bean工厂接口与实现类
package com.fly.utils.ioc;/** * bean工厂接口 */public interface BeanFactory { Object getBean(String id);}package com.fly.utils.ioc;import java.lang.reflect.Proxy;import java.util.HashMap;import java.util.List;import java.util.Map;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.io.SAXReader;import com.fly.utils.annotation.AOP;import com.fly.utils.aop.InvocationHandlerImpl;/** * 基于xml文件的bean工厂实现类 * 采用懒汉式单例模式 * 初始化时会加载对应的xml配置文件 * 默认加载applicationContext.xml */public class XmlBeanFactory implements BeanFactory { private static XmlBeanFactory INSTANCE; public static BeanFactory getFactory(String xmlPath) { if (INSTANCE == null) { synchronized(XmlBeanFactory.class) { if (INSTANCE == null) INSTANCE = new XmlBeanFactory(xmlPath); } } return INSTANCE; } public static BeanFactory getFactory() { if (INSTANCE == null) { synchronized(XmlBeanFactory.class) { if (INSTANCE == null) INSTANCE = new XmlBeanFactory(); } } return INSTANCE; } @SuppressWarnings("rawtypes") Map<String, Class> classMap = new HashMap<>(); Map<String, Object> map = new HashMap<>(); private XmlBeanFactory() { this("applicationContext.xml"); } private XmlBeanFactory(String xmlPath) { try { Document doc = new SAXReader() .read(BeanFactory.class.getClassLoader().getResourceAsStream(xmlPath)); Element root = doc.getRootElement(); List<Element> beans = root.elements("bean"); for (Element bean : beans) { String classValue = bean.attributeValue("class"); String id = bean.attributeValue("id"); System.out.println(id + " " + classValue); Class<?> clazz = Class.forName(classValue); //懒加载,用的时候实例化 classMap.put(id, clazz); } } catch (DocumentException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } @Override public Object getBean(String id) { Class<?> c = classMap.get(id); if (c != null) { //单例化 Object o = map.get(id); if (o == null) { try { o = c.newInstance(); if (c.isAnnotationPresent(AOP.class)) { o = Proxy.newProxyInstance(this.getClass().getClassLoader(), o.getClass().getInterfaces(), new InvocationHandlerImpl(o)); } map.put(id, o); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } } return map.get(id); }}
注意:Transaction注解需要加在interface中的方法上(由于扫描注解是在invocationhandler中进行的)
阅读全文
0 0
- 使用DBUtils、动态代理以及注解实现事务控制
- 通过使用反射+动态代理+注解来实现对事务的控制
- 使用动态代理+自定义注解控制数据库事务
- 解析动态代理模式与跟自定义注解配合使用以及事务注解原理
- JAVAWEB开发之Servlet3.0新特性的使用以及注解的详细使用和自定义注解的方法、动态代理的使用、利用动态代理实现细粒度的权限控制以及类加载和泛型反射
- 【Java基础】动态代理实现AOP之控制事务
- 注解+动态代理实现bookstore的权限控制
- JDK动态代理和CGLIB动态代理,实现Spring注解管理事务区别。
- 事务 概念 以及 使用 DBUtils 来执行事务操作
- 使用注解完成事务控制
- 使用ThreadLocal与JDK动态代理 实现事务AOP管理
- 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别。
- 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别。
- 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别。
- 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别。
- 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别
- 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别
- 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别。
- 又是一年1024程序员节
- Web Audio接收文件流导致无法快进的一个解决思路
- 深度学习之基础模型-mobileNet
- Java:按钮布局演示
- 10.24
- 使用DBUtils、动态代理以及注解实现事务控制
- Anti_TexturePacker工具
- 牛!何恺明包揽2项ICCV 2017最佳论文奖!这位高考状元告诉你什么是开挂的人生
- 【数论】错排公式
- struts2常用标签
- 信息学奥赛一本通(C++版) 第一部分 C++语言 第六章 函数
- 2017.10.21
- 清华姚班和100个“张小龙”| 中国AI天才养成计划
- Linux之redhat中虚拟机的安装教程