6.1) 트랜잭션 코드의 분리 메소드 분리 메일 발송 기술과 환경에도 종속적이지 않은 깔끔한 코드로 다듬어온 UserService이지만, 코드를 볼 때마다 찜찜하다. 스프링이 제공하는 트랜잭션 인터페이스를 썼음에도 비즈니스 로직이 주인이어야 할 메소드 안에 트랜잭션 경계설정을 위해 넣은 코드가 이름도 길고 더 많은 자리를 차지하고 있다. 하지만 논리적으로 따져봐도 트랜잭션의 경계는 분명 비즈니스 로직의 전후에 설정돼야 한다. 트랜잭션이 적용된 코드를 다시 한번 살펴보자. 자세히 살펴보면 비즈니스 로직 코드를 사이에 두고 트랜잭션 시작과 종료를 담당하는 코드가 앞뒤에 위치하고 있다. 또, 이 코드는 비즈니스 로직 코드에서 직접 DB를 사용하지 않기 때문에 트랜잭션 경계설정의 코드와 비즈니스 로직 코드 간에..
6.0) AOP AOP는 IoC/DI, 서비스 추상화와 더불어 스프링의 3대 기반기술의 하나다. 스프링에 적용된 가장 인기 있는 AOP의 적용 대상은 선언적 트랜잭션 기능이다. 서비스 추상화를 통해 많은 근본적인 문제를 해결했던 트랜잭션 경계설정 기능을 AOP를 이용해 더욱 세련되고 깔끔한 방식으로 바꿔보자. 그리고 그 과정에서 스프링이 AOP를 도입해야 했던 이유도 알아보자.
5.4) 메일 서비스 추상화 JavaMail을 이용한 메일 발송 기능 레벨이 업그레이드되는 사용자에게는 안내 메일을 발송해보자. 안내 메일을 발송하기 위해 해야 할 일은 두 가지가 있다. 먼저 사용자의 이메일 정보를 관리해야 한다. 업그레이드 작업을 담은 UserService의 upgradeLevel() 메소드에 메일 발송 기능을 추가하는 것이다. 사용자 정보에 이메일을 추가해보자. 레벨을 추가했을 때와 동일하게 DB의 User 테이블에 email 필드를 추가하고, User 클래스에 email 프로퍼티를 추가한다. 그에 따라 UserDao의 userMapper와 insert(), update()에 email 필드 처리 코드를 추가해준다. 그리고 수정된 코드가 정확히 동작하는지 확인하기 위해 테스트 코드도..
5.3) 서비스 추상화와 단일 책임 원칙 수직, 수평 계층구조와 의존관계 기술과 서비스에 대한 추상화 기법을 이용하면 특정 기술환경에 종속되지 않는 포터블한 코드를 만들 수 있다. UserDao와 UserService는 각각 담당하는 코드의 기능적인 관심에 따라 분리되고, 서로 불필요한 영향을 주지 않으면서 독자적으로 확장이 가능해진다. 같은 애플리케이션 로직을 담은 코드지만 내용에 따라 분리했으므로 같은 계층에서 수평적인 분리라고 볼 수 있다. 반면 트랜잭션의 추상화는 애플리케이션의 비즈니스 로직과 그 하위서 동작하는 로우레벨의 트랜잭션 기술이라는 아예 다른 계층의 특성을 갖는 코드를 분리한 것이다. 애플리케이션 로직의 종류에 따른 수평적인 구분이든, 로직과 기술이라는 수직적인 구분이든 모두 결합도가 ..
5.2) 트랜잭션 서비스 추상화 모 아니면 도 정기 사용자 레벨 관리 작업을 수행하는 도중에 네트워크가 끊기거나 서버에 장애가 생겨서 작업을 완료할 수 없다면? 그때까지 변경된 사용자의 레벨은 그대로 둘까요? 아니면 모두 초기 상태로 되돌려 놓아야 할까요? 일부 사용자는 레벨이 조정됐는데 일부는 안 됐다면 사용자의 반발이 심할 것으로 예상되기 때문에 작업이 중단된다면 그때까지 진행된 변경 작업도 모두 취소시키도록 결정했다. 그렇다면, 지금까지 만든 사용자 레벨 업그레이드 코드는 어떻게 동작할까? 테스트를 만들어서 확인해보자. 업그레이드 작업을 수행하다가 중간에서 예외가 던져지는 상황을 의도적으로 만들어 예외가 발생하게 만든다. 이를 위해 예외를 강제로 발생시키도록 애플리케이션 코드를 수정하는 것은 좋은 ..
5.1) 사용자 레벨 관리 기능 추가 필드 추가 지금까지 만들었던 UserDao는 CRUD라고 불리는 가장 기초적인 작업만 가능하다. User 오브젝트에 담겨 있는 사용자 정보를 등록, 조회, 수정, 삭제하는 것만 가능하다. 사용자 정보를 DB에 넣고 빼는 것을 제외하면 어떤 비즈니스 로직도 갖고 있지 않다. 간단한 비즈니스 로직을 추가해보자. 다수의 회원이 가입할 수 있는 인터넷 서비스의 사용자 관리 모듈에 적용해보자. 사용자 관리 기능은 단지 정보를 넣고 검색하는 것 외에도 정기적으로 사용자의 활동내역을 참고해서 레벨을 조정해주는 기능이 필요하다. 사용자 관리의 기본 로직은 정해진 활동 조건에 따라 사용자의 레벨을 주기적으로 변경한다. User 클래스에 사용자의 레벨을 저장할 필드를 추가하자. DB에..
4.2) 예외 전환 JDBC의 한계 JDBC는 자바를 이용해 DB에 접근하는 방법을 추상화된 API 형태로 정의해놓고, 각 DB 업체가 JDBC 표준에 따라 만들어진 드라이버를 제공하게 해준다. 내부 구현은 DB마다 다르겠지만 JDBC의 Connection, Statement, ResultSet 등의 표준 인터페이스를 통해 그 기능을 제공해주기 때문에 자바 개발자들은 표준화된 JDBC의 API에 익숙해지면 DB의 종류에 상관없이 일관된 방법으로 프로그램을 개발할 수 있다. 하지만 DB 종류에 상관없이 사용할 수 있는 데이터 액세스 코드를 작성하는 일은 쉽지 않다. 현실적으로 DB를 자유롭게 바꾸어 사용할 수 있는 DB 프로그램을 작성하는 데는 두 가지 걸림돌이 있다. 첫째 문제는 JDBC 코드에서 사용하..