FlexyPool如何同时支持连接代理和装饰器

代理人

FlexyPool监视连接池使用情况,因此需要拦截连接关闭方法调用。
为了简单起见,第一个版本为此目的依赖动态代理:

private static class ConnectionInvocationHandler implements InvocationHandler {public static final String CLOSE_METHOD_NAME = "close";private final Connection target;private final ConnectionCallback callback;public ConnectionInvocationHandler(Connection target, ConnectionCallback callback) {this.target = target;this.callback = callback;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if (CLOSE_METHOD_NAME.equals(method.getName())) {callback.close();}return method.invoke(target, args);}
}

代理调用的速度可能比装饰器慢,装饰器使用直接调用来调用目标方法。

由于所有连接池仍然使用代理,因此添加另一个代理层只会增加更多的呼叫时间开销,因此现在FlexyPool也支持连接装饰器。

装饰工

ConnectionDecorator包装基础数据库连接,将所有调用委派给实际的对象实例。 就像它的代理服务器代理一样,只有close方法可以执行任何额外的逻辑:

public class ConnectionDecorator implements Connection {private final Connection target;private final ConnectionCallback callback;public ConnectionDecorator(Connection target, ConnectionCallback callback) {this.target = target;this.callback = callback;}public Connection getTarget() {return target;}public ConnectionCallback getCallback() {return callback;}@Overridepublic Statement createStatement() throws SQLException {return target.createStatement();}@Overridepublic void close() throws SQLException {callback.close();target.close();}/***  More methods omitted for brevity sake*/public void setSchema(String schema) throws SQLException {ReflectionUtils.invoke(target,ReflectionUtils.getMethod(target, "setSchema", String.class),schema);}public String getSchema() throws SQLException {return ReflectionUtils.invoke(target,ReflectionUtils.getMethod(target, "getSchema"));}public void abort(Executor executor) throws SQLException {ReflectionUtils.invoke(target,ReflectionUtils.getMethod(target, "abort", Executor.class),executor);}public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {ReflectionUtils.invoke(target,ReflectionUtils.getMethod(target, "setNetworkTimeout", Executor.class, int.class),executor, milliseconds);}public int getNetworkTimeout() throws SQLException {return (Integer) ReflectionUtils.invoke(target,ReflectionUtils.getMethod(target, "getNetworkTimeout"));}
}

您可能已经注意到,某些方法使用Java Reflection而不是直接方法调用:

  • abort()
  • getSchema()
  • setSchema()
  • getNetworkTimeout()
  • setNetworkTimeout()

这些方法已添加到Java 1.7中,使用Java 1.6编译项目时,直接调用将失败。 因为Java 1.6是大多数FlexyPool模块的最低要求,所以这些方法通过Java反射调用转发传入的方法调用。 省略这些方法不是可选的,因为在1.7 JVM上, Connection装饰器将没有这些方法,并且将引发类装入错误。

在至少使用Java 1.7的项目中,FlexyPool还提供了Java7ConnectionDecorator

public class Java7ConnectionDecorator extends ConnectionDecorator {public Java7ConnectionDecorator(Connection target, ConnectionCallback callback) {super(target, callback);}@Overridepublic void setSchema(String schema) throws SQLException {getTarget().setSchema(schema);}@Overridepublic String getSchema() throws SQLException {return getTarget().getSchema();}@Overridepublic void abort(Executor executor) throws SQLException {getTarget().abort(executor);}@Overridepublic void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {getTarget().setNetworkTimeout(executor, milliseconds);}@Overridepublic int getNetworkTimeout() throws SQLException {return getTarget().getNetworkTimeout();}
}

此类不是核心库的一部分,包含在单独的Java 1.7兼容模块中。 要使用它,您需要添加以下Maven依赖项:

<dependency><groupId>com.vladmihalcea.flexy-pool</groupId><artifactId>flexy-pool-core-java7</artifactId><version>${flexy-pool.version}</version>
</dependency>

服务发现机制

从一开始,FlexyPool就为配置ConnectionProxyFactory实例提供了支持,因此切换到装饰器不需要任何繁琐的代码重构。

1.2.4发行版之前,默认的连接提供程序是JdkConnectionProxyFactory ,它使用动态代理。
从1.2.4开始,FlexyPool使用连接装饰器作为默认的连接拦截机制。

实际的装饰器版本在运行时解析,并且加载机制由以下组件构成:

flexypoolconnectionproxydecorator

实际的连接装饰器工厂通过以下方法解决:

public ConnectionDecoratorFactory resolve() {int loadingIndex = Integer.MIN_VALUE;ConnectionDecoratorFactory connectionDecoratorFactory = null;Iterator<ConnectionDecoratorFactoryService> connectionDecoratorFactoryServiceIterator = serviceLoader.iterator();while (connectionDecoratorFactoryServiceIterator.hasNext()) {try {ConnectionDecoratorFactoryService connectionDecoratorFactoryService = connectionDecoratorFactoryServiceIterator.next();int currentLoadingIndex = connectionDecoratorFactoryService.loadingIndex();if (currentLoadingIndex > loadingIndex) {ConnectionDecoratorFactory currentConnectionDecoratorFactory = connectionDecoratorFactoryService.load();if (currentConnectionDecoratorFactory != null) {connectionDecoratorFactory = currentConnectionDecoratorFactory;loadingIndex = currentLoadingIndex;}}} catch (LinkageError e) {LOGGER.info("Couldn't load ConnectionDecoratorFactoryService on the current JVM", e);}}if (connectionDecoratorFactory != null) {return connectionDecoratorFactory;}throw new IllegalStateException("No ConnectionDecoratorFactory could be loaded!");
}

就像MetricsFactory一样 ,每个连接装饰器工厂都有一个关联的服务提供者 。 可以在运行时加载多个此类服务提供程序(默认的Java 1.6连接修饰器服务或Java 1.7之一)。 根据索引(最新的Java版本优先)和当前的JVM JDBC版本支持(在Java 1.6运行时环境中无法解析Java 1.7连接装饰器)进行选择。

结论

装饰器比代理器承担更多的配置开销,但是如果您想减少最后的性能下降,则值得考虑直接方法调用的优势。

翻译自: https://www.javacodegeeks.com/2015/08/how-does-flexypool-support-both-connection-proxies-and-decorators.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/357869.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

集合视图控制器(CollectionViewController) 、 标签控制器(TabBarController) 、 高级控件介绍...

1 创建集合视图&#xff0c;设置相关属性以满足要求 1.1 问题 集合视图控制器UIConllectionViewController是一个展示大量数据的控制器&#xff0c;系统默认管理着一个集合视图UICollectionView&#xff0c;功能几乎和UITableViewController差不多&#xff0c;能够以多行多列的…

【APICloud系列|24】 MNNavigationMenu模块(导航菜单)的实现

导读:MNNavigationMenu 是一个导航栏菜单,开发者可自定义其中的样式和按钮个数,超出屏幕部分可左右拖动查看。 模块详情:http://www.apicloud.com/mod_detail/12417 index.html <!doctype html> <html> <head><meta charset="utf-8">&…

mysql2教程_mySQL 教程 第2章 安装和介绍mySQL

设置mySQL字符集支持中文的字符集是utf8&#xff0c;该设置可以更改mySQL配置文件进行全局设置&#xff0c;也可以针对数据库设置&#xff0c;也可以针对表设置&#xff0c;也可以针对列设置。字符集更改后新插入的数据生效&#xff0c;对以前不生效。练习1&#xff1a;更改MyS…

java 更新订单状态_Java 8状态更新

java 更新订单状态即将到来的Java SE 8发行版的两大新语言功能是Lambda Expressions和Modularity。 这两天的状态更新都已经发布。 我会与您分享链接&#xff0c;因此您可能会在假期中通读它们 Oracle计划在2013年中期发布Java SE 8。 Lambda项目 Lambda项目以及JSR-335希望提…

基于JBoss Fuse 6.2的JBoss BPM微服务集成指南

今年年初&#xff0c;我们宣布了JBoss BPM Suite令人兴奋的示例项目&#xff0c;该项目围绕一个正在运行的在线Travel Agency项目展开。 最初是利用Web服务&#xff0c;后来我们在JBoss Fuse的帮助下迁移到微服务 。 随着JBoss Fuse 6.2的发布&#xff0c;我们希望重新访问该…

mysql zip 还原_mysql 压缩还原数据库

MySQL数据库备份和还原的常用命令其实很多情况下mysql备份就是采用了这些命令&#xff0c;例如&#xff1a;mysql导入和导出数据linux自动定时备份web程序和mysql数据库备份MySQL数据库的命令mysqldump -hhostname -uusername -ppassword databasename > backup...文章无声胜…

jvm调试工具_调试JVM

jvm调试工具在某些&#xff08;极少数&#xff09;情况下&#xff0c;您可能会遇到使JVM本身崩溃的情况。 我最近通过将ThreadGroup的名称设置为null来进行管理 。 在这些情况下&#xff0c;调试JVM本身很有用&#xff0c;这样可以更精确地定位崩溃。 这是执行此操作的步骤&…

遮罩窗体弹出登录页面代码实现

先上效果图(本人喜欢胡巴&#xff0c;背景用了胡巴)&#xff0c;鼠标滑过页面&#xff0c;图片变暗&#xff0c;透明度为0.4&#xff0c;同时弹出登录窗口。 接下来先看css代码(写的可能不是很规范&#xff0c;根据调整样式顺序写的) body{background-color: black;width: 100%…

【APICloud系列|27】 UICalendar模块(日历)的实现

导读:UICalendar 是一个日历选择模块;可自定义日历的样式,添加特殊日期标注,切换月份,设置指定日期;用于实现常用的日期选择,日历展示功能 模块地址 UICalendar 是一个日历选择模块;可自定义日历的样式,添加特殊日期标注,切换月份,设置指定日期;用于实现常用的日期…

使用Camel从WildFly 8向WebLogic 12发送JMS消息

系统集成是一个很好的挑战。 特别是当您在寻找通信标准和可靠的解决方案时。 在当今的微服务世界中&#xff0c;每个人都在谈论REST服务和基于http的协议。 实际上&#xff0c;对于大多数企业项目来说&#xff0c;这往往是远远不够的&#xff0c;而这些项目通常具有更复杂的要求…

【APICloud系列|28】 UIChatBox 模块(聊天输入框)的实现

导读:UIChatBox 模块是一个聊天输入框模块,开发者可自定义该输入框的功能 项目结构: config.xml <?xml version="1.0" encoding="UTF-8"?><widget id="A6909001303255" version="0.0.1"> <name>UIChatbox<…

mysql索引参数_MySQL索引介绍

索引由数据库表中一列或者多列组合而成&#xff0c;其作用是提高对表中数据的查询速度。创建索引是指在某个表的一列或者多列上建立一个索引&#xff0c;用来提高对表的访问速度&#xff0c;创建索引由三种方法&#xff1a;在创建表的时候创建&#xff0c;在已存在的表上创建和…

【APICloud系列|31】百度导航功能的实现

导读:百度导航基础功能。d用到了bMap模块,baiduNavigation模块,UIListView模块。样式完全来自AUI。js用到了zepto.j 效果图: 项目结构: index.html <!doctype html> <html> <head><meta charset="utf-8"><meta name="viewport…

osgi简介_OSGi:简介

osgi简介为基于Java的系统创建的OSGi提供了模块化系统的框架。 OSGi使得可以定义每个单独模块与其他模块的依赖关系&#xff0c;并使用户能够控制生命周期并动态更改系统的每个组件。 OSGi是一个规范&#xff0c;最常见的实现可以算作Equinox &#xff0c; Apache Felix和Knopl…

GC基本算法及C++GC机制

前言 垃圾收集器是一种动态存储分配器&#xff0c;它自动释放程序不再需要的已分配的块&#xff0c;这些块也称为垃圾。在程序员看来&#xff0c;垃圾就是不再被引用的对象。自动回收垃圾的过程则称为垃圾收集&#xff08;garbage collection&#xff09;。在一个支持垃圾收集的…

【APICloud系列|32】 aMapNavigation高德地图导航的实现

导读:aMapNavigation 模块封装了高德导航的sdk,支持语音导航功能。用户可自行算路策略类型。开发者只需输入起点终点经纬度即可轻松集成高德导航功能,本模块是由第三方模块开发者提供,使用本模块需在线云编译安装包。 效果图: 项目结构: index.html <!doctype html&…

JDK 9早期版本安装后的Windows注册表清理

在我的上一篇博文中 &#xff0c;我演示了在安装早期版本的JDK 9&#xff08;内部版本68&#xff09;之后围绕Oracle Java符号链接 &#xff08;基于Windows的计算机上的C:\ProgramData\Oracle\Java\javapath\目录&#xff09;的问题的解决方案。这似乎阻止了早期&#xff08;更…

java实现网上招标系统

导读:本设计尝试用JSP在网络上架构一个下沙派威客网,以推进网站无纸化,过程电子化,管理智能化的发展。本文从理论和实践两个角度出发,对一个具有数据分析功能的下沙派威客网进行设计与实现分析。论文首先较为详尽地介绍了面向对象分析与设计的有关概念与技术,特别深入介绍…

java实现俄罗斯方块项目

导读:俄罗斯方块项目,基本功能包括:游戏主界面显示模块、方块及数据显示模块、方块移动控制模块、游戏界面颜色控制模块、游戏进度、等级控制模块等。本项目结构如下: (1)游戏主界面显示模块: 显示游戏和帮助两个菜单; 游戏使用功能键盘,得分 等级; (2)画布…

js数组操作大全

shift:删除原数组第一项&#xff0c;并返回删除元素的值&#xff1b;如果数组为空则返回undefined Javascript代码 var a [1,2,3,4,5]; var b a.shift(); //a:[2,3,4,5] b:1 unshift:将参数添加到原数组开头&#xff0c;并返回数组的长度 Javascript代码 var a [1,2,…