Java事务之六——使用动态代理(Dynamic Proxy)

VMware VSAN 高级参数介绍(测试用) VSAN 的策略驱动让我们看到了VSAN无穷的潜力,其设计思路相当新颖,在一个基础资源池上使用策略就能实现不同对象的区分服务,而目前没有其他厂家能到VMware这样的高度。 VSAN 呈现给用户配置很简单,但实际上设计及后台比较复杂。笔者无意间发现了VSAN的隐藏高级参数设置,有很多好玩的选项想分享出来。这些参数全部是针对每主机进行设置的。VSAN 中有很多默认设置,这些设置应该都是研发人员多次测试得出的最优值,修改可能导致环境异常,并不建议修改! 目录 参数1:全闪配置下 SSD 写缓存最大. 阅读详情

Java事务之六——使用动态代理(Dynamic Proxy)

本文转载自:http://www.cnblogs.com/davenkin/archive/2013/02/24/java-tranaction-6.html,侵删。

  在本系列的上一篇文章中,我们讲到了使用Template模式进行事务管理,这固然是一种很好的方法,但是不那么完美的地方在于我们依然需要在service层中编写和事务处理相关的代码,即我们需要在service层中声明一个TransactionTemplate。在本篇文章中,我们将使用Java提供的动态代理(Dynamic Proxy)功能来完成事务处理,你将看到无论是在service层还是DAO层都不会有事务处理代码,即他们根本就意识不到事务处理的存在。使用动态代理完成事务处理也是AOP的一种典型应用。

 

  这是一个关于Java事务处理的系列文章,请通过以下方式下载github源代码:

git clone https://github.com/davenkin/java_transaction_workshop.git

 

  Java动态代理的基本原理为:被代理对象需要实现某个接口(这是前提),代理对象会拦截对被代理对象的方法调用,在其中可以全然抛弃被代理对象的方法实现而完成另外的功能,也可以在被代理对象方法调用的前后增加一些额外的功能。在本篇文章中,我们将拦截service层的transfer方法,在其调用之前加入事务准备工作,然后调用原来的transfer方法,之后根据transfer方法是否执行成功决定commit还是rollback。

 

  首先定义一个TransactionEnabledProxyManager类:

复制代码
package davenkin.step5_transaction_proxy;

import davenkin.step3_connection_holder.TransactionManager;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class TransactionEnabledProxyManager
{
    private TransactionManager transactionManager;

    public TransactionEnabledProxyManager(TransactionManager transactionManager)
    {

        this.transactionManager = transactionManager;
    }

    public Object proxyFor(Object object)
    {
        return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), new TransactionInvocationHandler(object, transactionManager));
    }
}

class TransactionInvocationHandler implements InvocationHandler
{
    private Object proxy;
    private TransactionManager transactionManager;

    TransactionInvocationHandler(Object object, TransactionManager transactionManager)
    {
        this.proxy = object;
        this.transactionManager = transactionManager;
    }

    public Object invoke(Object o, Method method, Object[] objects) throws Throwable
    {
        transactionManager.start();
        Object result = null;
        try
        {
            result = method.invoke(proxy, objects);
            transactionManager.commit();
        } catch (Exception e)
        {
            transactionManager.rollback();
        } finally
        {
            transactionManager.close();
        }
        return result;
    }
}
复制代码

 

  通过调用该类的proxyFor方法,传入需要被代理的对象(本例中为service对象),返回一个代理对象。此后,在调用代理对象的transfer方法时,会自动调用TransactionIvocationHandler的invoke方法,在该方法中,我们首先开始事务,然后执行:

 result = method.invoke(proxy, objects);

 

  上面一行代码执行的是原service层的transfer方法,如果方法执行成功则commit,否则rollback事务。

 

  由于与事务处理相关的代码都被转移到了代理对象中,在service层中我们只需调用DAO即可:

复制代码
package davenkin.step5_transaction_proxy;

import davenkin.BankService;
import davenkin.step3_connection_holder.ConnectionHolderBankDao;
import davenkin.step3_connection_holder.ConnectionHolderInsuranceDao;
import javax.sql.DataSource;

public class BareBankService implements BankService
{
    private ConnectionHolderBankDao connectionHolderBankDao;
    private ConnectionHolderInsuranceDao connectionHolderInsuranceDao;

    public BareBankService(DataSource dataSource)
    {
        connectionHolderBankDao = new ConnectionHolderBankDao(dataSource);
        connectionHolderInsuranceDao = new ConnectionHolderInsuranceDao(dataSource);
    }

    public void transfer(final int fromId, final int toId, final int amount)
    {
        try
        {
            connectionHolderBankDao.withdraw(fromId, amount);
            connectionHolderInsuranceDao.deposit(toId, amount);
        } catch (Exception e)
        {
            throw new RuntimeException();
        }
    }
}
复制代码

 

  如何,上面的BareBankService中没有任何事务处理的影子,我们只需关注核心业务逻辑即可。

 

  然后在客户代码中,我们需要先创建代理对象(这在Spring中通常是通过配置实现的):

复制代码
  @Test
    public void transferFailure() throws SQLException
    {
        TransactionEnabledProxyManager transactionEnabledProxyManager = new TransactionEnabledProxyManager(new TransactionManager(dataSource));
        BankService bankService = new BareBankService(dataSource);
        BankService proxyBankService = (BankService) transactionEnabledProxyManager.proxyFor(bankService);

        int toNonExistId = 3333;
        proxyBankService.transfer(1111, toNonExistId, 200);

        assertEquals(1000, getBankAmount(1111));
        assertEquals(1000, getInsuranceAmount(2222));
    }
复制代码

 

  在上面的测试代码中,我们首先创建一个BareBankService对象,然后调用transactionEnabledProxyManager的proxyFor方法生成对原BareBankService对象的代理对象,最后在代理对象上调用transfer方法,测试运行成功。

 

  可以看到,通过以上动态代理实现,BareBankService中的所有public方法都被代理了,即他们都被加入到事务中。这对于service层中的所有方法都需要和数据库打交道的情况是可以的,本例即如此(有且只有一个transfer方法),然而对于service层中不需要和数据库打交道的public方法,这样做虽然也不会出错,但是却显得多余。在下一篇文章中,我们将讲到使用Java注解(annotation)的方式来声明一个方法是否需要事务,就像Spring中的Transactional注解一样。

YOLO-World:从入门到实战的多模态目标检测全指南 想象一下,你给模型一张“公园”的图片,再输入文字“红色的郁金香”,它能直接在图中框出所有红色郁金香的位置——这就是多模态目标检测:结合图像视觉信息和文本语义信息,同时完成“是什么”(分类)和“在哪里”(定位)的任务。传统目标检测(如YOLOv5、YOLOv8)只能识别预定义的类别(比如训练时学过“猫”“狗”),但多模态目标检测摆脱了“类别预定义”的限制,只要文本能描述,它就能检测,这就是“开放词汇检测(Open-Vocabulary Detection)”的魅力。 阅读详情

相关推荐

OpenCV实战:5分钟搞定图像拼接(附Python代码)

本文通过OpenCV实战教程,详细讲解如何使用Python在5分钟内完成图像拼接。重点介绍`findHomography`函数和单应性矩阵的应用,提供完整的代码示例和常见问题解决方案,帮助开发者快速掌握图像拼接技术。

weixin_26833503的博客 120

【Java】【Spring】【事务的使用】

【Java】【Spring】【事务的使用】

时光与简的博客 5408

华中科技大学 计算机组成原理 educoder Logisim平台 计算机数据表示实验

本文主要是对 计算机数据表示实验的笔记和相关Logisim平台的图,供大家学习交流使用。 需要源文件或者源代码,可以留言评论! 目录实验目的第1关:汉字国标码转区位码实验第2关:汉字机内码获取实验第3关:偶校验编码设计第4关:偶校验解码电路设计第5关:16位海明编码电路设计第6关:16位海明解码电路设计第7关:海明编码流水传输实验第8关:16位CRC并行编解码电路设计第9关:CRC编码流水传输实验实验结果: 实验目的 本实训将帮助同学们巩固对计算机中数据表示方法的理解,要求能设计汉字国标码与区位码之间的转换

weixin_48383580的博客 2万+

JAVA面试题分享七十八:Transaction Template和@Transaction的区别?

在现代软件开发中,事务处理是必不可少的一部分。当多个操作需要作为一个整体来执行时,事务可以确保数据的完整性和一致性,并避免出现异常和错误情况。在SpringBoot框架中,我们可以使用声明式事务和编程式事务来管理事务处理。其中事务的坑也是不少,比较常见的就是事务失效,大家可以看看!这篇博客将重点探讨这两种事务处理方式的源码实现、区别、优缺点、适用场景以及实战。我们来接着说事务,里面还涉及到三个知识点,大家可以自行百度好好了解!事务的特性事务的传播行为隔离级别。

之乎者也·的博客 1728

通达信源码-主力建仓-AI投研图灵室出品

AI投研图灵室1:=3*SMA((CLOSE-LLV(LOW,75))/(HHV(HIGH,75)-LLV(LOW,75))*100,20,1)-2*SMA(SMA((CLOSE-LLV(LOW,75))/(HHV(HIGH,75)-LLV(LOW,75))*100,20,1),15,1);AI投研图灵室2W:=100-100*(HHV(HIGH,14)-CLOSE)/(HHV(HIGH,14)-LLV(LOW,14));AI投研图灵室3:=SMA(SMA(AI投研图灵室2,3,1),3,1);

qq_57222058的博客 4383

具身智能落地实战:制造业、物流与电力的工业级方案设计

具身智能是一种融合感知、推理与物理执行的智能范式,其核心在于构建具备因果建模能力、多模态闭环反馈和实时动作规划的行动主体。区别于通用AI或传统自动化,它依托多模态大模型、高精度力觉/触觉传感及Sim2Real仿真技术,实现对真实物理环境的深度理解与自适应交互。技术价值体现在可解释性决策、毫秒级跨模态协同与零停机容错能力,已规模化应用于制造业质检、物流破损鉴定、电力绝缘子巡检等强约束工业场景。本文聚焦‘行业应用方案解决方案’这一高频搜索需求,系统拆解从工位筛选、分层架构设计到72小时现场交付的全链路工程方法论

weixin_30952479的博客 300

Java多线程下使用TransactionTemplate控制事务

本文展示了在Java的多线程环境下使用Spring的TransactionTemplate控制事务的提交与回滚,当任何一个子线程出现异常时,所有子线程都将回滚。

cm777的博客 2833

ubuntu17.04 UHD 驱动出错

ubuntu 17.04 源码安装UHD

xrh003的博客 1万+

java 事务模板_编程事务-基于transactionTemplate模板实现

编程事务编程事务-实现方式PlatformTransactionManager(平台事务管理器)TransactionTemplate(模板事务)Spring团队推荐使用transactionTemplate事务模板来实现事务实现步骤模板事务(TransactionTemplate)步骤: 获取模板对象=>选择事务结果类型=>业务数据操作处理平台事务管理器(PlatformTransa...

weixin_39638468的博客 1062

14、微电网控制方法与建模分析

本文详细探讨了微电网的控制方法与建模分析,包括逆变器的小信号状态空间模型、网络模型、负载模型及其组合形成的完整微电网模型。通过对系统特征值和灵敏度因子的分析,揭示了不同模式与系统参数之间的关系。文章还提出了多个研究问题,如岛式系统控制器设计、风力发电控制、并网变换器控制等,为微电网的稳定性分析和优化控制提供了理论支持和实践方向。

elastic6hunter的博客 123

【学习系列】SAP RAP 22:Excel文件上传和读取(非扩展&扩展方式)

本文介绍了在RAP中实现Excel文件上传处理的三种方法:1) 使用@Semantics.largeObject注解实现简单上传下载,但限制在ObjectPage页面使用;2) 通过自定义action弹窗实现上传功能,但存在无法自动刷新列表等限制;3) 结合CustomUIExtension实现更灵活的完整功能,但需要UI5开发技能。文章详细说明了每种方法的实现步骤,包括数据库表设计、注解配置、前端界面开发和后端处理逻辑,并比较了各自的优缺点。最后通过一个处理不同币种数据的示例,展示了如何实现业务处理逻辑。

DeveloperMrMeng的博客 623

TransactionTemplate编程式事务

TransactionTemplate学习相关记录

lyh59的博客 1万+

把外部系统一键装进 SAP Build Work Zone:从零开始创建 HTML5 URL App

HTML5 URL App 是一种轻量级解决方案,可将外部网页或系统入口快速集成到SAP企业门户中。开发者只需在manifest.json中配置目标URL、导航模式等参数,无需开发完整前端应用。该方案利用SAP BTP的HTML5 Application Repository集中存储静态资源,通过HTML5 Apps Content Provider将应用暴露给子账号,最终在SAP Build Work Zone中以Fiori磁贴形式呈现。文章详细介绍了manifest.json的关键配置、三种基础设施组件

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 241

Java事务处理全解析(六)—— 使用动态代理(Dynamic Proxy)完成事务

在本系列的上一篇文章中,我们讲到了使用Template模式进行事务管理,这固然是一种很好的方法,但是不那么完美的地方在于我们依然需要在service层中编写和事务处理相关的代码,即我们需要在service层中声明一个TransactionTemplate。在本篇文章中,我们将使用Java提供的动态代理(Dynamic Proxy)功能来完成事务处理,你将看到无论是在service层还是DAO层

huilangeliuxin的专栏 9852

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

java事务学习笔记(六)--使用动态代理(Dynamic Proxy)完成事务

在本系列的上一篇文章中,我们讲到了使用Template模式进行事务管理,这固然是一种很好的方法,但是不那么完美的地方在于我们依然需要在service层中编写和事务处理相关的代码,即我们需要在service层中声明一个TransactionTemplate。在本篇文章中,我们将使用Java提供的动态代理(Dynamic Proxy)功能来完成事务处理,你将看到无论是在service层还是DAO层

JordanInShenzhen的博客 832

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

java事务全解析(六)--使用动态代理(Dynamic Proxy)完成事务

在本系列的上一篇文章中,我们讲到了使用Template模式进行事务管理,这固然是一种很好的方法,但是不那么完美的地方在于我们依然需要在service层中编写和事务处理相关的代码,即我们需要在service层中声明一个TransactionTemplate。在本篇文章中,我们将使用Java提供的动态代理(Dynamic Proxy)功能来完成事务处理,你将看到无论是在service层还是DAO层

java小强的博客 303

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

解释Java中的动态代理(Dynamic Proxy)及其用例

动态代理是Java中一个强大的技术点,可以让我们在运行时为一个或多个接口动态地创建代理实现。通过代理类的实现,我们能够在方法调用链中插入自定义逻辑,而不必修改原始对象的代码。动态代理的灵活性开启了很多高级编程技术的可能性,特别是在企业级应用和框架中,像Spring AOP(面向方面编程)就重度依赖动态代理。在Spring AOP中,动态代理被用来实现横切关注点,比如声明式事务管理、安全、日志等。

java永无止境! 1992

java设计模式:动态代理Dynamic_Proxy详解 (使用场景:事务、日志、监控等)

编者的话: 如果你想灵活,对方法执行前后(添加代码),进行监控(比如:方法运行[多少毫秒、记录日志、事务提交或回滚、权限监控、数据拦截、数据过滤]等)。时,动态代理模式,最适合你。 特别提示: 1、本案例主要是阐述动态代理的原理,及其模拟过程,可以提示对动态代理的理解和掌握。 2、JDK6以上版本,系统自带的有动态代理类Proxy,我们可以直接用,我们只需要专注于我们的InvocationHandler就可以了。

血煞长虹 的专栏 3223

Java事务处理全解析——使用动态代理(Dynamic Proxy)完成事务

在本系列的上一篇文章中,我们讲到了使用Template模式进行事务管理,这固然是一种很好的方法,但是不那么完美的地方在于我们依然需要在service层中编写和事务处理相关的代码,即我们需要在service层中声明一个TransactionTemplate。在本篇文章中,我们将使用Java提供的动态代理(Dynamic Proxy)功能来完成事务处理,你将看到无论是在service层还是DAO层

ltd010的博客 655

Java动态代理(dynamic proxy)

代理模式通过代理对象拦截目标对象的访问,实现访问控制和功能增强。静态代理需实现相同接口并持有目标对象,动态代理则利用Java的Proxy和InvocationHandler在运行时生成代理类。

huangpf_vcx 605
上一篇: Java事务之五——Template模式
下一篇: Java事务之七——使用Transactional注解
TaiSung
博客等级 码龄15年 49粉丝 132原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值