- 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 을 제공