Home
📍

4장. 스프링에서는 예외 처리를 어떻게 하는가?

Tag
챕터 내용 정리
- Checked Exception: Exception 서브 클래스 중 RuntimeException을 상속하지 않은 것. 처리 안하면(catch, throws) 컴파일 에러 발생 - Unchecked Exception: RuntimeException을 상속한 클래스. NPE, IAE 등 - 예외 회피: 호출한 쪽으로 예외를 던져버림 - 콜백/템플릿처럼 긴밀한 다른 오브젝트에게 예외처리 책임을 지게 하거나 - 던지는 쪽에서 예외를 다루는 게 최선이거나
Plain Text
복사
JdbcTemplate을 적용한 이후 throw SQLException 이 사라짐
갑자기 개발자 코드에서 발견되는 하면 안되는 예외처리 예시?
try catch로 예외 발생 잡은 이후 아무 조치 취하지 않음(프린트하고 끝)
throws로 예외 선언하기 귀찮아서 메소드 선언에 throws Exception 기계적으로 붙임
그래서 예외를 어떻게 다루어야 하는가?
checked exception: 명시적인 처리가 필요한 예외를 사용하고 다루는 방법
Exception class
RuntimeException 상속 X ⇒ 체크 ⇒ 반드시 예외 처리 코드 함께 작성해야함
RuntimeException 상속 ⇒ 언체크 ⇒ NPE, IAE ⇒ 미리 조건 체크만 하면예외상황에서 발생하진 않음
근데 체크 예외는 불필요하다?
체크 예외가 예외처리를 강제하기 때문에 하면 안 되는 예외처리 코드가 남발됨
⇒ 예상 가능한 예외는 체크 예외로 만들지 X
그래서 일반적인 예외처리 방법
예외 복구: 예외 상황을 파악하고 문제를 해결해서 정상 상태로 돌린다
예외처리 회피: 예외처리를 하지 않고 자신을 호출한 쪽으로 던져버림
예외 전환: 예외를 적절한 예외로 전환해서 메소드 밖으로 던짐
의미를 분명하게 하는 예외로 바꿔준다거나
예외를 처리하기 쉽고 단순하게 만들기 위해 포장(wrap) 한다거나
⇒ 어차피 복구 못하는 예외면 런타임 예외로 포장해서 던짐
⇒ 예외처리 서비스 등을 만들어서 로그 남기고 메시지 보여주기
그래서 JdbcTemplate를 사용하면 SQLException은 왜 사라지는가?
일단 SQLException 은 복구 불가 → 런타임 예외
SQLException 의 에러 코드는 DB에 종속됨 → DB에 독립적인 예외로 전환해야 됨
그래서 스프링은 DataAccessException 으로 DB에 독립적으로 적용할 수 있는 추상화된 런타임 예외 계층을 제공(런타임 예외로 SQLException을 포장)
근데 확실히 생각해보면 JDBC뿐만이 아니고 JPA나 MyBatis 쓸 때도 유사한 Exception이 발생하긴 함 ⇒ 라이브러리에서 DataAccessException
DAO를 DB 접근 기술에서 독립시켜야 함 ⇒ 인터페이스 도입, 런타임 예외 전환, 추상화된 예외 전환 필요
public interface UserDao { public void add(User user); ... } public class UserDaoJdbc implements UserDao {}
Java
복사
[EX] 낙관적인 락킹을 구현한다고 했을 때 DataAccessException 을 상속하는 예외 클래스를 사용/정의하여 에외처리 가능
그러면 상황에 따라 다르겠지만 예외처리할 때 일관되게 구현되어있는 예외를 발생시키는 게 일반적인지? 아니면 커스텀해서 상황에 맞게 구체적으로 작성하는게 일반적인지?
결론
복구할 수 없는 예외 → 런타임 예외(혹은 런타임 예외를 상속한 예외)로 처리
스프링은 데이터 액세스 기술(DB/ORM)의 종류에 관계 없이 DataAccessException 을 제공