[이펙티브 자바][아이템 9] try-finally 보다 try-with-resources 를 사용하라 - 컴도리돌이
많은 개발자들이 자주 사용하는 try-finally 블록은 리소스를 명시적으로 해제해야 하는 경우에 자주 사용됐지만, 이 방법에는 몇 가지 단점이 있어요. 코드가 장황해지고, 가독성이 떨어지며, 예외가 발생할 경우 자칫 리소스 해제가 제대로 이루어지지 않을 가능성이 생기죠. 특히 스프링 부트 환경에서 여러 외부 리소스나 파일, 데이터베이스 연결 등을 다룰 때 더욱 신중하게 할 필요가 있습니다. 🧐
이런 문제를 해결하기 위해 등장한 것이 try-with-resources인데, 이 구조는 자바 7에서 도입되었고, 자동으로 리소스를 해제해 주는 것이 특징이에요. 리소스를 명시적으로 닫지 않아도 되기 때문에 코드가 훨씬 간결해지고, 예외가 발생하더라도 안정하게 리소스를 관리할 수 있죠.
Connection conn = null;
Statement stmt = null;
try {
conn = dataSource.getConnection();
stmt = conn.createStatement();
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
위 코드는 리소스를 안전하게 해제하기 위해서 finally에서 자원을 해제해 주는데, 자원을 해제하기 위한 코드가 많이 들어가서 매우 복잡해요. 그리고 중첩된 try-catch 블록 때문에 가독성도 떨어지죠. 반면에, try-with-resources를 사용하면 아래처럼 단순하게 작성할 수 있어요.
try (Connection conn = dataSource.getConnection();
Statement stmt = conn.createStatement()) {
} catch (SQLException e) {
e.printStackTrace();
}
코드의 가독성이 훨씬 좋아지지 않았나요? 😊 역시 코드는 짧고 간단해야지 보기 좋고 정신 건강에도 좋은 거 같아요. 자원 관리는 어디서나 중요하며, Spring boot에서는 주로 JdbcTemplate나 EntityManager와 같은 컴포넌트들이 내부적으로 데이터베이스 연결을 관리해 주지만, 직접적으로 리소스를 다룰 때는 try-with-resources를 사용하는 것이 훨씬 더 권장되는 패턴이에요.
public String readFileContent(String filePath) throws IOException {
try (BufferedReader reader = Files.newBufferedReader(Paths.get(filePath))) {
return reader.lines().collect(Collectors.joining("\n"));
}
}
스프링 기반의 애플리리케이션에서도 자원을 효율적으로 관리하는 것이 중요해요. 예를 들어, 파일 I/O 작업이나 DB 연결 작업에서 여러 자원이 얽힐 수 있는 상황에서, try-with-resources는 가독성과 안전성을 동시에 보장하죠. 보통 서비스 레이어에서 리소스를 직접 관리할 필요는 없지만, 특정 상황에서 직접 파일을 다루거나 외부 자원을 사용해야 할 때도 있습니다.