분류 전체보기 1341

Ch05. 자바 예외 이해 - 예외 포함과 스택 트레이스

예외를 전환할 때는 꼭! 기존 예외를 포함해야 한다. 그렇지 않으면 스택 트레이스를 확인할 때 심각한 문제가 발생한다. PrintEx Test @Test public void printEx() { Controller controller = new Controller(); try { controller.request(); }catch (Exception e){ //e.printStackTrace(); log.info("ex", e); } } 로그를 출력할 때 마지막 파라미터에 예외를 넣어주면 로그에 스택 트레이스를 출력할 수 있다. 예) log.info("message={}", "message", ex) , 여기에서 마지막에 ex를 전달하는 것을 확인할 수 있다. 이렇게 하면 스택 트레이스에 로그를 출력할..

Ch05. 자바 예외 이해 - 언체크 예외 활용

SQLException을 런타임 예외인 RuntimeSQLException으로 변환했다. ConnectException 대신에 RuntimeConnectException 을 사용하도록 바꾸었다. 런타임 예외이기 때문에 서비스, 컨트롤러는 해당 예외들을 처리할 수 없다면 별도의 선언 없이 그냥 두면 된다. Test public class UnCheckedAppTest { @Test public void unchecked() { Controller controller = new Controller(); Assertions.assertThatThrownBy(() -> controller.request()).isInstanceOf(RuntimeSQLException.class); } static class Co..

Ch05. 자바 예외 이해 - 체크 예외 활용

언제 언체크 예외를 사용하고, 언제 체크 예외를 사용해야 할까??? 기본 원칙 2가지 기본적으로 언체크(런타임) 예외를 사용하자. 체크 예외는 비즈니스 로직상 의도적으로 던지는 예외에만 사용하자. 이 경우 해당 예외를 잡아서 반드시 처리해야 하는 문제일 때만 체크 예외를 사용해야 한다. 예를 들어서 다음과 같은 경우가 있다. 체크 예외 예) 계좌 이체 실패 예외 결제시 포인트 부족 예외 로그인 ID, PW 불일치 예외 물론 이 경우에도 100% 체크 예외로 만들어야 하는 것은 아니다. 다만 계좌 이체 실패처럼 매우 심각한 문제는 개발자가 실수로 예외를 놓치면 안 된다고 판단할 수 있다. 이 경우 체크 예외로 만들어 두면 컴파일러를 통해 놓친 예외를 인지할 수 있다. 체크 예외의 문제점 체크 예외는 컴파일..

Ch05. 자바 예외 이해 - 언체크 예외 기본 이해

RuntimeException과 그 하위 예외는 언체크 예외로 분류된다. 언체크 예외는 말 그대로 컴파일러가 예외를 체크하지 않는다는 뜻이다. 언체크 예외는 체크 예외와 기본적으로 동일하다. 차이가 있다면 예외를 던지는 throws를 선언하지 않고, 생략할 수 있다. 이 경우 자동으로 예외를 던진다. 체크 예외 VS 언체크 예외 체크 예외: 예외를 잡아서 처리하지 않으면 항상 throws 에 던지는 예외를 선언해야 한다. 언체크 예외: 예외를 잡아서 처리하지 않아도 throws 를 생략할 수 있다. Test @Slf4j public class UncheckedTest { @Test public void unchecked_catch() { Service service = new Service(); serv..

Ch05. 자바 예외 이해 - 체크 예외 기본 이해

Exception과 그 하위 예외는 모두 컴파일러가 체크하는 체크 예외이다. 단 RuntimeException 은 예외로 한다. 체크 예외는 잡아서 처리하거나, 또는 밖으로 던지도록 선언해야 한다. 그렇지 않으면 컴파일 오류가 발생한다. @Slf4j public class CheckedTest { @Test public void checked_catch() { Service service = new Service(); service.callCatch(); } @Test public void checked_throw() { Service service = new Service(); Assertions.assertThatThrownBy(() -> service.callThrow()) .isInstanceOf..

Ch05. 자바 예외 이해 - 예외 계층 & 예외 기본 규칙

예외 계층 Object : 예외도 객체이다. 모든 객체의 최상위 부모는 Object 이므로 예외의 최상위 부모도 Object이다. Throwable : 최상위 예외이다. 하위에 Exception과 Error 가 있다. Error : 메모리 부족이나 심각한 시스템 오류와 같이 애플리케이션에서 복구 불가능한 시스템 예외이다. 애플리케이션 개발자는 이 예외를 잡으려고 해서는 안된다. 상위 예외를 catch로 잡으면 그 하위 예외까지 함께 잡는다. 따라서 애플리케이션 로직에서는 Throwable 예외도 잡으면 안 되는데, 앞서 이야기한 Error 예외도 함께 잡을 수 있기 때문에다. 애플리케이션 로직은 이런 이유로 Exception부터 필요한 예외로 생각하고 잡으면 된다. 참고로 Error 도 언체크 예외이다...

Ch04. 스프링과 문제 해결(트랜잭션) - 스프링 부트의 자동 리소스 등록

@Bean public DataSource dataSource() { return new DriverManagerDataSource(URL, USERNAME, PASSWORD); } @Bean public PlatformTransactionManager transactionManager() { return new DataSourceTransactionManager(dataSource()); } 기존에는 이렇게 데이터 소스와 트랜잭션 매니저를 직접 스프링 빈으로 등록해야 했다. 그런데 스프링 부트가 나오면서 많은 부분이 자동화되었다. (더 오래전에 스프링을 다루어왔다면 해당 부분을 주로 XML로 등록하고 관리했을 것이다.) 데이터 소스 - 자동 등록 스프링 부트는 데이터 소스( DataSource )를 스..

Ch04. 스프링과 문제 해결(트랜잭션) - 트랜잭션 문제 해결(트랜잭션 AOP 정리)

비즈니스 로직 대신 스프링 빈으로 등록된 AOP 프록시 객체에서 트랜잭션 처리 로직을 동작시킨다. 내부에서 비즈니스 로직이 실행되면 unchecked 예외가 발생 시 rollback을 수행, 정상 흐름이면 commit을 동작시킨다. 선언적 트랜잭션 관리 vs 프로그래밍 방식 트랜잭션 관리 선언적 트랜잭션 관리(Declarative Transaction Management) @Transactional 애노테이션 하나만 선언해서 매우 편리하게 트랜잭션을 적용하는 것을 선언적 트랜잭션 관리라 한다. 선언적 트랜잭션 관리는 과거 XML에 설정하기도 했다. 이름 그대로 해당 로직에 트랜잭션을 적용하겠다라고 어딘가에 선언하기만 하면 트랜잭션이 적용되는 방식이다. 프로그래밍 방식의 트랜잭션 관리(programmati..

Ch04. 스프링과 문제 해결(트랜잭션) - 트랜잭션 문제 해결(트랜잭션 AOP 적용)

MemberServiceV3_3 /** * 트랜잭션 - @Transactional AOP */ @Slf4j public class MemberServiceV3_3 { private final MemberRepositoryV3 memberRepository; public MemberServiceV3_3(MemberRepositoryV3 memberRepository) { this.memberRepository = memberRepository; } @Transactional public void accountTransfer(String fromId, String toId, int money) throws SQLException { bizLogic(fromId, toId, money); } private v..

Ch04. 스프링과 문제 해결(트랜잭션) - 트랜잭션 문제 해결(트랜잭션 AOP 이해)

지금까지 트랜잭션을 편리하게 처리하기 위해서 트랜잭션 추상화도 도입하고, 추가로 반복적인 트랜잭션 로직을 해결하기 위해 트랜잭션 템플릿도 도입했다. 트랜잭션 템플릿 덕분에 트랜잭션을 처리하는 반복 코드는 해결할 수 있었다. 하지만 서비스 계층에 순수한 비즈니스 로직만 남긴다는 목표는 아직 달성하지 못했다. 이럴 때 스프링 AOP를 통해 프록시를 도입하면 문제를 깔끔하게 해결할 수 있다 프록시 도입 public class TransactionProxy { private MemberService target; public void logic() { //트랜잭션 시작 TransactionStatus status = transactionManager.getTransaction(..); try { //실제 대상 ..