繁体   English   中英

java中的try-catch-finally块

[英]try-catch-finally block in java

根据我的理解,我希望遵循最终释放资源的最佳实践,以防止任何连接泄漏。 这是我在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块中关闭然后执行return语句? TIA。

你的理解是正确的。 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();
}

你也可以创建一个AutoCloseable为您dynamoDB连接(即调用包装shutdownclose ),并做

try (DynamoDB con = getDynamoDBConnection()) {
    // Do whatever you need to do with con
} catch (ApplicationSpecificException e) {
    // deal with it gracefully
}

是的,dynamoDB将返回一个空连接,因为dynamoBD.shutdow()将在return语句Always之前执行。

虽然我没有回答你关于finally块一直被执行的问题(已经有几个问题的答案),但我想分享一些关于如何使用DynamoDB客户端的信息。

DynamoDB客户端是一个线程安全的对象,旨在在多个线程之间共享 - 您可以为您的应用程序创建一个全局的线程,并在您需要的地方重用该对象。 通常,客户端创建由某种IoC容器(例如Spring IoC容器)管理,然后由容器提供给依赖注入的任何代码。

在底层,DynamoDB客户端维护一个HTTP连接池,用于通信DynamoDB端点并使用此池中的连接。 可以通过在构造客户端时传递ClientConfiguration对象的实例来配置池的各种参数。 例如,其中一个参数是允许的最大打开HTTP连接数。

基于上述理解,我会说,由于DynamoDB客户端管理HTTP连接的生命周期,因此资源泄漏实际上不应该与使用DynamoDB客户端的代码有关。

我们如何“模仿”错误,看看会发生什么? 这就是我的意思:

___情况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");
    }

___Case 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");
    }

这些练习可以是使用单元测试的更完美的地方,更具体地说是模拟测试 我建议你仔细看看JMockit ,这将帮助你更容易地编写这样的测试。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM