우아한테크코스 4기

level 2 스프링

giron 2022. 6. 10. 00:09
728x90

스프링이 관리할 객체를 어떻게 지정할까?

컨테이너 설정 방법에는 3가지가 있다.

@ComponenetScan이 하위 클래스들을 쭉 훑으면서 @Component로 설정된 빈들을 자바 빈으로 관리하도록 설정한다.

어떤 객체를 스프링이 관리해야할지?

의존성이 있다면 스프링이 관리해주는게 좋다고 생각한다! 스프링이 의존성을 관리해주기 때문이다.

계속 의존성이 연결되는걸 스프링의 빈이 관리해주니 편하다.

예를 들면, spring-boot-starter-jdbc: 의존성을 추가하고 jdbcTemplate을 빈에서 불러오는데 빈으로 의존성이있는 20개 정도가 있다. 이처럼 무수히 많은 의존성들을 스프링이 관리해주기떄문에 좋다.

 

경험으로는 spark web에서 spring으로 전환하니깐 의존성관리를 해줘서 엄청 편했다! 빈으로 등록하면 자동으로 가져와서 사용되기 때문이다.

 

스프링은 빈들을 싱글톤으로 관리하기 때문에 매번 new로 생성하지 않아도 돼서 리소스관리에도 좋다.

 

DI 방식에서 생성자 주입을 선호하는 이유

spring-core

생성자 주입을 추천하는 이유는 공식 문서에서 설명해준다.

불변으로 만들수 있다
또한 요구된 의존성이 null이 아님을 보장할수 있다.(의존성 주입에 실패하면 객체가 생성되지 않기 때문이다.)
생성자 주입 구성 요소는 항상 완전히 초기화된 상태로 클라이언트(호출) 코드에 반환됩니다. 참고로 많은 수의 생성자 인수는 나쁜 코드 냄새이며, 이는 클래스에 너무 많은 책임이 있을 수 있으며 적절한 문제 분리를 더 잘 처리하기 위해 리팩토링해야 함을 의미합니다.

여기서 null이 아님을 보장한다는게 얼마나 좋은지 와닿는데, 체스 미션을 스프링으로 진행하면서 의존성 주입이 잘못 되었을 때, NPE가 발생한 경우가 있었다. 이때 어디서 왜 NPE가 발생하는지 원인을 찾기 힘들었고 혹시 빈 주입의 문제인가..?라는 의심으로 원인을 찾아갔던 경험이 있다. 이를 통해 생성자 주입 방식의 장점을 알아보았다.

 

비즈니스 로직

도메인에 넣도록 하자. 서비스는 도메인 로직들을 조합하여 흐름을 구현하는 레이어라고 생각되기 때문에 비즈니스 로직은 도메인에 넣어두고 서비스에서 호출하여 활용하자.

체스미션에서 Spark 기반 웹 을 작성하다가 스프링으로 변환 후, Controller를 추가하고 의존성 연결해줘야지 했는데 스프링이 빈으로 자동으로 등록해주고 관리해줘서 좋았다!

 

브라운의 ATDD

ATDD를 통한 효율적인 개발 프로세스

TDD vs ATDD

ATDD 하는 이유?

1. 생산성 증가 - 코드 작성 전 테스트를 작성하므로 요구사항이 명확해진다.

2. 작업의 명확한 시작과 끝

3. 빠른 피드백 - 인수테스트를 잘 작성해두면 서버를 띄우지 않고 빠르게 피드백 받을 수 있다.

 

Acceptance Test

- 클라이언트 입장에서 진행하는 테스트

- 보통 마지막 단계에서 수행하는 테스트

- 요구사항 검증 - 시나리오 형식으로 검증

 

정상적인 시나리오 : 일반적으로 성공하는 테스트

비정상적인 시나리오 : 예외가 발생하는 테스트

 

인수테스트는 E2E or 통합테스트 or API테스트

인수테스트는 테스트 검증하는 대상에 따라 달라질수 있다.

 

예시
api테스트 방법

SpringBootTest할때는 Context를 캐싱하여 재사용한다. (즉, Caching처리를 한다.) 매번 띄울때마다 시간이 오래 걸리기 때문이다.

따라서 DatabaseCleanUp - truncate, EntityManager, 등 id 1로 초기화등의 방법을 해도 좋다.

---

Mock을 사용하면 프로덕션 코드에 의존적인 테스트가 되기 쉽다는 단점이 있다. - 프로덕션 코드가 변경되면 테스트도 변경되기 때문이다. 명확한 단위 테스트 가능.

 

@Configuration과 @Bean

configuration없어도 수동으로 빈 등록이 가능하다. 하지만 이렇게되면 싱글톤을 확실하게 보장할수 없다. 

예를들어 아래와 같이 @Configuration이 없이 사용하면 a라는 빈이 b와 c의 빈이 생성될 때, 2번 생성된다.

public class SignletonBeanTest { 

    @Bean 
    public A a() {
        return new A(); 
    } 
    
    @Bean 
    public B b() { 
        return new B(a()); 
    } 
    
    @Bean 
    public C c() { 
        return new C(a()); 
    }

여기서 @Configuration을 붙여주면 CGLIB를 통한 프록시를 사용하여 항상 싱글톤을 사용하도록 보장할 수 있다.

 

 

 

 

728x90