Блок try-catch-finally в 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? ТИА.
4 ответа
Ваше понимание верно. 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 (которая вызывает shutdown
внутри close
) и делать
try (DynamoDB con = getDynamoDBConnection()) {
// Do whatever you need to do with con
} catch (ApplicationSpecificException e) {
// deal with it gracefully
}
Да, DynamoDB вернет пустое соединение как dynamoBD.shutdow()
будет выполнен перед оператором return Всегда.
Хотя я не отвечаю на ваш вопрос о том, что блок 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");
}
___ Случай 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, который поможет вам гораздо легче писать такие тесты.