根据我的理解,我希望遵循最终释放资源的最佳实践,以防止任何连接泄漏。这是我在HelperClass中的代码。
public static DynamoDB getDynamoDBConnection()
{
try
{
dynamoDB = new DynamoDB(new AmazonDynamoDBClient(new ProfileCredentialsProvider()));
}
catch(AmazonServiceException ase)
{
//ase.printStackTrace();
slf4jLogger.error(ase.getMessage());
slf4jLogger.error(ase.getStackTrace());
slf4jLogger.error(ase);
}
catch (Exception e)
{
slf4jLogger.error(e);
slf4jLogger.error(e.getStackTrace());
slf4jLogger.error(e.getMessage());
}
finally
{
dynamoDB.shutdown();
}
return dynamoDB;
}
我的疑问是,既然 finally 块将被执行,无论如何,dynamoDB将返回空连接,因为它将在 finally 块中关闭,然后执行返回声明? TIA。
答案 0 :(得分:10)
您的理解是正确的。 dynamoBD.shutdown()
将始终在return dynamoDB
之前执行。
我不熟悉您正在使用的框架,但我可能会按如下方式组织代码:
public static DynamoDB getDynamoDBConnection()
throws ApplicationSpecificException {
try {
return new DynamoDB(new AmazonDynamoDBClient(
new ProfileCredentialsProvider()));
} catch(AmazonServiceException ase) {
slf4jLogger.error(ase.getMessage());
slf4jLogger.error(ase.getStackTrace());
slf4jLogger.error(ase);
throw new ApplicationSpecificException("some good message", ase);
}
}
并将其用作
DynamoDB con = null;
try {
con = getDynamoDBConnection();
// Do whatever you need to do with con
} catch (ApplicationSpecificException e) {
// deal with it gracefully
} finally {
if (con != null)
con.shutdown();
}
您还可以为您的dynamoDB连接创建AutoCloseable
包装器(在shutdown
内调用close
)并执行
try (DynamoDB con = getDynamoDBConnection()) {
// Do whatever you need to do with con
} catch (ApplicationSpecificException e) {
// deal with it gracefully
}
答案 1 :(得分:1)
是的,dynamoDB将返回一个空连接,因为dynamoBD.shutdow()
将在return语句之前执行,总是。
答案 2 :(得分:1)
虽然我没有回答你关于finally块一直被执行的问题(已经有几个问题的答案),但我想分享一些关于如何使用DynamoDB客户端的信息。
DynamoDB客户端是一个线程安全的对象,旨在在多个线程之间共享 - 您可以为应用程序创建一个全局的线程,并在您需要的地方重用该对象。通常,客户端创建由某种IoC容器(例如Spring IoC容器)管理,然后由容器提供给通过依赖注入的任何代码。
在底层,DynamoDB客户端维护一个HTTP连接池,用于通信DynamoDB端点并使用此池中的连接。可以通过在构造客户端时传递ClientConfiguration对象的实例来配置池的各种参数。例如,其中一个参数是允许的最大打开HTTP连接数。
基于上述理解,我会说,由于DynamoDB客户端管理HTTP连接的生命周期,因此资源泄漏不应该与使用DynamoDB客户端的代码有关。
答案 3 :(得分:0)
我们如何“模仿”错误,看看会发生什么?这就是我的意思:
___案例1 ___
try{
// dynamoDB = new DynamoDB(new AmazonDynamoDBClient(new ProfileCredentialsProvider()));
throw new AmazonServiceException("Whatever parameters required to instantiate this exception");
} catch(AmazonServiceException ase)
{
//ase.printStackTrace();
slf4jLogger.error(ase.getMessage());
slf4jLogger.error(ase.getStackTrace());
slf4jLogger.error(ase);
}
catch (Exception e)
{
slf4jLogger.error(e);
slf4jLogger.error(e.getStackTrace());
slf4jLogger.error(e.getMessage());
}
finally
{
//dynamoDB.shutdown();
slf4jLogger.info("Database gracefully shutdowned");
}
___案例2 ___
try{
// dynamoDB = new DynamoDB(new AmazonDynamoDBClient(new ProfileCredentialsProvider()));
throw new Exception("Whatever parameters required to instantiate this exception");
} catch(AmazonServiceException ase)
{
//ase.printStackTrace();
slf4jLogger.error(ase.getMessage());
slf4jLogger.error(ase.getStackTrace());
slf4jLogger.error(ase);
}
catch (Exception e)
{
slf4jLogger.error(e);
slf4jLogger.error(e.getStackTrace());
slf4jLogger.error(e.getMessage());
}
finally
{
//dynamoDB.shutdown();
slf4jLogger.info("Database gracefully shutdowned");
}
这些练习可以是使用单元测试的完美场所,更具体地说是mock tests。我建议你仔细看看JMockit,这将有助于你更容易地编写这样的测试。