日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2023/12/3 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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使用連接裝飾器作為默認的連接攔截機制。

實際的裝飾器版本在運行時解析,并且加載機制由以下組件構成:

實際的連接裝飾器工廠通過以下方法解決:

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

總結

以上是生活随笔為你收集整理的FlexyPool如何同时支持连接代理和装饰器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。