본문 바로가기

Back-End/토비의 스프링3

(24)
토비의 스프링 6장(2) - 고립된 단위 테스트 고립된 단위 테스트단위 테스트는 당연히 작은 단위어야 한다. 쉽고, 빠르고, 명확하기 때문이다. 복잡한 의존관계 속의 테스트 UserService 테스트를 위해 필요한 구조DB와 데이터를 주고 받기 위한 UserDaoJdbc트랜잭션 처리를 위한 Transaction Manager메일 전송을 위한 MailSender문제점간단한 UserService 테스트를 위해서는 DB, Transaction 등 의존 관계를 명시해줘야 한다. 테스트하기 복잡하고, 환경에 영향을 받는다. 테스트 대상 오브젝트 고립시키기 단위테스트 vs 통합테스트둘 중에 어떤걸 써야할까?항상 단위 테스트를 먼저 고려한다외부 리스소를 사용해야 하는경우만 통합 테스트. 외부와의 의존관계는 모두 차단하고 필요에 따라 목 오브젝트 등의 테스트 대역..
토비의 스프링 6장(1) - AOP 트랜잭션 코드의 분리 지난 포스팅http://happyer16.tistory.com/entry/5%EC%9E%A52-%EC%8A%A4%ED%94%84%EB%A7%81-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EC%84%9C%EB%B9%84%EC%8A%A4-%EC%B6%94%EC%83%81%ED%99%94?category=692836에서 UserService에서 트랜잭션이 필요했다. 스프링에서 제공해주는 인터페이스를 썼음에도 불구하고 비즈니스 로직에 길고 더러운 코드가 있어 찝찝함을 감출 수 없다. 개요등장배경스프링이 도입하려는 이유장점 ( 예제로 선언적 트랜잭션 기능을 살펴보자 )메소드 분리[ 리팩토링 전 - 서로 정보도 주고 받지 않고 관련이 없는 트랜잭션 코드 / 비즈니스 코드가 섞여 있다. ]..
토비의 스프링 - 4장. 예외 토비의 스프링 - 4장. 예외이번 포스팅에서는 스프링의 데이터 엑세스 기능에 담겨있는 예외처리와 관련된 접근 방법에 대해 알아본다. 예외의 종류와 특징Errorjava.lang.Error 클래스의 서브클래스이다. 주로 자바 VM에서 발생하는 에러이기 때문에 신경쓰지 않아도 되고 애플리케이션 코드에서 잡으려고 해서도 안된다. ( OutOfMemoryError, ThreadDeath ) Exception과 체크 예외java.lang.Exception은 애플리케이션 코드의 작업 중에 예외상황이 발생했을 경우에 사용한다. RuntimeException : catch, throw를 강제하지 않음 ( ex : NullPointerException )체크 예외 : RuntimeException을 상속받지 않은 나머지..
5-4장. 메일 서비스 추상화 메일 서비스 추상화고객으로부터 사용자 레벨 관리에 관한 새로운 요청사항이 들어온 경우라면?User에 email 추가upgradeLevel()에 메일 발송 기능 추가JavaMail이 포함된 코드의 테스트테스트 코드를 돌리면 SMTP host에 연결할 수 없다고 에러가 날 것이다. 그렇다면 아래 처럼 테스트 서버를 구축하는건 어떨까? UserService ---> JavaMail ---> 메일 서버 ---> 테스트용 메일 서버 매번 메일이 발송되는건 바람직하지 못하다. 메일 발송은 부하가 큰 작업일 뿐 아니라, JavaMail은 검증된 라이브러리이다. 따라서 JavaMail API를 통해 요청이 들어간다는 보장만 있다면 굳이 테스트할 때마다 JavaMail을 구동시킬 필요가 없다. UserService --..
5-3장. 서비스 추상화와 단일 책임 원칙 서비스 추상화스프링의 트랜잭션 서비스 추상화 기법을 이용해 다양한 트랜잭션 기술을 일관된 방식으로 제어할 수 있게 됐다. 수직, 수평 계층 구조와 의존관계추상화 기법을 통해 특정 기술환경에 종속되지 않는 코드르 만들었다. UserDao나 UserService는 각각 담당하는 코드의 기능적인 관심에 따라 분리되었다. 같은 애플리케이션 로직을 담은 코드지만 내용에 따라 분리했다. 같은 계층에서 수평적인 분리라고 할 수 잇다. 트랜잭션 추상화는 이와 좀 다르다. 애플리케이션 코드와 그 하위에서 동작하는 로우레벨의 트랜잭션 기술이라는 다른 계층의 특성을 갖는 코드를 분리한 것이다. UserService : 사용자 관리에 대한 비즈니스 로직UserDao : 데이터를 어떻게 가져오고 등록할 것인가에 대한 데이터 엑..
5-2장. 스프링 - 트랜잭션 서비스 추상화 사용자 레벨 업그레이드 코드를 완성했다. 하지만, 레벨 업그레이드 작업 중 에러가 발생하여 일부 유저만 수정되었다면 어떻게 처리해야할까? 고객들의 불만을 일으키지 않기 위해, 원상태로 돌려놓아야 한다. 즉, upgradeLevels()를 하나의 작업단위인 트랜잭션을 적용해야 한다. JDBC 트랜잭션의 트랜잭션 경계설정setAutoCommit(false)로 트랜잭션의 시작을 선언하고 commit() 또는 rollback()으로 트랜잭션을 종료하는 작업을 트랜잭션 경계설정이라 한다.Connection c = dataSource.getConnection(); c.setAutoCommit(false); // 트랜잭션 시작 try { // 트랜잭션 하나의 작업 PreparedStatement st1 = c.pre..
5장. 스프링 - 서비스 추상화(사용자 레벨 관리 기능 추가) 서비스 추상화예제를 살펴보면서 스프링이 어떻게 성격이 비슷한 여러 기술을 추상화하고 이를 일관된 방법으로 사용할 수 있도록 해주는지 살펴보자. ( 서비스 추상화 ) 예제 : 사용자의 활동내역을 참고해서 사용자 레벨 관리 기능 추가1. Level Enum 사용하기Level enum 만들기장점 1 : int 타입으로 레벨 상수를 사용하는 것보다 의미 있는 상수로 사용할 수 있음 ( int형 setLevel(10000)과 같은 버그 코드는 컴파일 에러가 나지 않음 ) 장점 2 : varchar 타입보다 DB 용량을 많이 차지하지 않는다. public enum Level { BASIC(1), SILVER(2), GOLD(3); private final int value; Level(int value) { thi..
1.3-IoC 컨테이너 : 프로토타입과 스코프 IoC 컨테이너 : 프로토타입과 스코프스프링의 빈은 기본적으로 싱글톤으로 만들어진다. 요청이 있을때마다 매번 애플리케이션 로직을 담은 오브젝트를 새로 만드는 것은 비효율적이기 때문이다. 한 빈 오브젝트에 여러 개의 스레드가 동시에 접근하기 때문에 상태 값을 인스턴스 변수에 저장해두고 사용할 수 없다. DB나 로직에 의해 새로 만들어지는 DTO 등은 파라미터나 리턴 값으로 전달하면 싱글톤으로 사용하는데 아무 문제가 없다. 먼저 스코프에 따라 어떻게 되는지 테스트 코드를 살펴보자. @RunWith(SpringRunner.class) @SpringBootTest public class ScopeTests { @Test public void singletonScope() { ApplicationContext a..
1.2-IoC 컨테이너 : 빈 설정하기 1.2-IoC 컨테이너 : 빈 설정하기스프링에서 IoC 컨테이너의 가장 기본적인 역할은 코드를 대신해서 애플리케이션을 구성하는 오브젝트를 생성하고 관리하는 것이다.( 이전 내용은 http://happyer16.tistory.com/183?category=692836 을 참고 ) 그렇다면 IoC 컨테이너가 자신이 만들 오브젝트가 무엇인지 어떻게 알 수 있을까?빈을 만들기 위한 설정 메타정보가 담긴 BeanDefinition을 IoC 컨테이너가 활용한다.빈 생성을 위한 메타정보가 무엇이 있는지?메타 정보를 표현하는 다양한 방법이 2가지에 대해 살펴보자. IoC 컨테이너 : 빈 설정 메타정보스프링에서는 오브젝트를 IoC 컨테이너가 생성하고 관리하는 과정에서 필요한 세밀한 방법을 제공한다. 하지만, 우리는 클래..
1.1-IoC 컨테이너 : 빈 팩토리와 애플리케이션 컨텍스트 IoC 컨테이너 : 빈 팩토리와 애플리케이션 컨텍스트스프링의 핵심 개념 중 하나인 IoC 컨테이너와 DI 기술에 대해 살펴보자. 스프링 애플리케이션에서는 객체의 생성, 사용, 제거, 관계설정 등을 애플리케이션 코드 대신 독립된 컨테이너가 담당한다. 코드 대신 객체에 대한 제어권을 갖고 있다고 해서 IoC(제어의 역전)이라 부른다. IoC 컨테이너 = 빈 팩토리 또는 애플리케이션 컨텍스트빈 팩토리 : 객체의 생성과 객체 사이의 런타임 관계를 설정하는 DI 시점에서는 빈팩토리라 함애플리케이션 컨텍스트 : 앤터프라이즈 애플리케이션을 개발하는데 필요한 몇가지 기능이 추가된 것 public interface ApplicationContext extends EnvironmentCapable, ListableBean..