본문 바로가기
학습로그

[레벨2] 체스-Spring 적용 학습로그

by 에드박 2021. 4. 23.

학습로그

[Architecture] 상위 계층과 하위계층의 참조

내용

  • 상위 계층에서 하위 계층을 참조하는것은 괜찮지만 하위 계층이 상위 계층을 참조하는것은 피해야 합니다.
  • 하위 계층이 상위계층을 참조하게 되면 상위계층의 변화에 의해 하위 계층이 변경될 여지를 주기 때문입니다.
  • 계층을 나누고 상위 계층이 하위계층을 의존하게 하는것은 상위 계층이 변경되더라도 하위 계층은 그대로 사용할 수 있도록 하기 위함입니다. 

[spring] spring5.2 springboot 2.2 부터 추가된 test 기능들 - 2

내용

  • OutputCaptureExtension
    • OutputCapture에 관한 내용 -> OutputCapture란? log나 print를 찍은 즉, console에 찍힌 로그를 캡쳐해서 그 내용을 검증하는 기능
    • junit4 에서는 @ Rule 애너테이션을 이용해서 사용할 수 있었지만 junit5에서는 사용할 수 없었다.(junit5에서는 @ Rule 애너테이션이 존재하지 않아서)
    • junit5 에서 OutputCaptureExtension 클래스를 사용해서 로그에 대한 테스트가 가능하다.
  • ApplicationArguments
    • @ SpringBootTest 애너테이션을 사용한다면 args 속성에 값을 주고 사용할 수 있다.
    • 예시) @ SpringBootTest(args = "--foo=bar")
  • Springboot 2.2 부터는 junit5 를 기본 디펜던시로 받고 있다.
  • junit4에서는 테스트 클래스의 기본 생성자가 있어야했기 때문에 필드를 이용한 주입을 주로 사용했다.
public SomeClassTest {
    @Autowired
    private SomethingObject object;
    
    테스트하는 내용...
}
  • Spring 5.0 부터는 junit5를 이용해 생성자 주입을 받을 수 있게 됐다.
public SomeClassTest {
    private SomethingObject object;
    
    @Autowired
    public SomeClassTest(SomethingObject object) {
        this.object = object;
    }
    
    테스트하는 내용...
}
  •  테스트에서 생성자를 통해 주입받을 때 @ Autowired 애너테이션을 생략하는 방법
    • 애너테이션 사용 - @ TestConstructor(autowireMode = AutowireMode.ALL)
    • 위와는 반대로 AutowireMode.ANNOTATED를 설정하면 @ Autowired를 반드시 명시해줘야함(기본설정값)
    • properties 파일에 spring.test.constructor.autowire.mode=ALL 명시해주기 (전역 설정)
@TestConstructor(autowiredMode = AutowiredMode.ALL)
public SomeClassTest {
    private SomethingObject object;
    
    // @Autowired 생략해도 자동 DI를 해준다.
    public SomeClassTest(SomethingObject object) {
        this.object = object;
    }
    
    테스트하는 내용...
}

참고 자료

 


[spring - DI] 왜 스프링팀에서도 의존성 주입 방법 중 생성자 주입을 권장하는가? - 2

내용

Spring Team recommends
“Always use constructor based dependency injection in your beans. Always use assertions for mandatory dependencies”.

 

항상 Bean에서 생성자 기반 종속성 주입을 사용하십시오.

  • 생성자 주입 방법 3가지
    • 생성자
    • 필드
    • setter
  • 필드 주입이 가장 간단하게 작성할 수 있는데 어째서 생성자 주입인가?
    • ex) @Autowired private MyClass myClass;
  • 각각의 의존성 주입 방법의 빈 생성 시점
    • Setter : 먼저 기본 생성자(인자가 없는)를 호출하여 빈을 생성한 후에 의존관계를 주입하려는 빈의 setter를 호출한다.
public SomethingClass {
    private Charlie charlie;
    
    public SomthingClass() {
    }
    
    @Autowired
    public void setCharlie(Charlie charlie) {
        this.charlie = charlie;
    }
}
  •  필드 : 주입 받으려는 빈의 생성자를 호출하여 빈을 찾거나 빈을 빈 팩터리에 등록한다. 후에 주입하려는 필드에 주입해준다.
public SomethingClass {
    @Autowired
    private Charlie charlie;
    
    public SomthingClass() {
    }
}
  •  생성자 : 생성자로 객체를 생성하는 시점에 필요한 빈을 주입한다.
public SomethingClass {
    private final Charlie charlie;
    
    @Autowired
    public SomthingClass(Charlie charlie) {
        this.charlie = charlie;
    }
}
  • 생성자 주입의 장점
    • 순환 참조를 방지할 수 있다.(실행 단계에서 서로 빈으로 참조하려고 하기 때문에 순환참조 에러를 실행단계에서 문제를 알 수 있다.)
      • 생성자나 세터 주입방법은 애플리케이션 구동까지는 문제가 없지만 해당 코드를 실행했을 때 문제가 발생할 수 있습니다.
    • 테스트에 용이하다.
    • 의존성이 명시적으로(좀 더 명확하게) 드러난다. -> 나쁜 코드의 냄새(?)를 맡을 수 있다 -> 리팩토링의 필요성을 느낄 수 있다.
    • 불변성(immutability) -> 필드를 final로 선언가능
    • 오류 방지 가능(불변성으로 인한 안전함)

참고자료

생성자 주입을 @ Autowired를 사용하는 필드 주입보다 권장하는 이유

Dependency Injection With Spring


[spring-mvc-test] Controller Layer 테스트 RestAssured VS MockMvc - 3

내용

  • MockMvc - Controller Layer 만 테스트
    • 웹 애플리케이션을 애플리케이션 서버에 배포하지 않고도 스프링 MVC의 동작을 재현할 수 있는 라이브러리
    • 대부분 Controller Layer 단위 테스트에 사용
    • 실제 서버 환경과 동일한 @ SpringBootTest 를 사용할 필요가 없다.
    • @ WebMvcTest 를 통해 Presentation Layer Bean 들만 불러옵니다.
    • 그 외에 빈은 Mock 객체 설정을 해서 순수 Controller 로직만을 테스트한다.
  • RestAssured - 웹 요청에 대한 전체적인 로직을 테스트
    • Rest 웹 서비스를 검증하기 위한 라이브러리
    • End-To-End Test (전 구간 테스트에 사용) -> Rest 웹 서비스의 전체 로직을 테스트(?)
    • @ SpringBootTest 로 실제 요청을 보내서 전체적인 로직을 테스트합니다.
    • 실제 요청시 필요한 다양한 메서드도 제공
    • 사용자 관점의 인수테스트에 좋습니다.
  • 의존성
    • MockMvc - Spring test 의존성이 추가되어 있다면 기본적으로 포함되어 있음
    • RestAssured - 직접 의존성을 추가해줘야함
      • testImplementation 'io.rest-assured:rest-assured:3.3.0'
  • 속도
    • MockMvc - @ WebMvcTest 를 사용할 수 있어서 Presentation Layer의 빈들만 로드하므로 속도가 빠름
    • RestAssured - @ SpringBootTest 를 사용해야하므로 Spring 에 등록된 모든 빈들을 로드하므로 속도가 느림
      • RestAssured에 별도의 구성을 만들어주면 @MockMvc 사용이 가능함
  • 가독성
    • RestAssured 는 BDD 스타일의 코드가 가능하므로 MockMvc 보다 가독성이 좋다.

참고 자료


[Spring] Spring VS SpringBoot - 3

학습 내용 정리

  • SpringBoot 는 Spring에서 기본설정을 더해준 것이다.
  • @SpringBootApplication 애너테이션에는 3가지 애너테이션이 포함되어 있다.
    • @SpringBootConfiguration : 스프링 부트의 설정을 나타내는 애너테이션. @Configuration과 똑같은 기능을 가지고 있으며  @SpringBootConfiguration을 기준으로 자동설정 구성을 찾는다는 것이 @Configuration과 다른 점 입니다.
    • @ComponentScan : 위치를 따로 설정하지 않으면 현재 패키지를 기준으로 하위 패키지까지 @Component 애너테이션이 붙은 클래스를 읽어들입니다.
    • @EnableAutoConfiguration : 자동설정의 핵심 애너테이션. spring-boot-autoconfigure 안에 spring.factories파일의 키값 EnableAutoConfiguration의 뱉류값들을 자동 설정 빈으로 등록합니다.


[REST API] REST 란 무엇인가? - 4

학습 내용 정리

  • Rest는 Web의 장점을 최대한 활용하기 위해 만들어짐
  • Rest 구성
    • 자원(Resource) - URI
    • 행동(Verb) - HTTP METHOD
    • 표현(Representations)
  • Rest의 특징
    • 유니폼 인터페이스(Uniform Interface) : URI로 지정한 리소스에 대한 조작을 통일돠고 한정적인 인터페이스로 수행하는 아키텍쳐를 의미
      • admin 페이지를 들어간다고 하면
      • http://www.charlie.com?auth=admin 이 아니라
      • http://www.charlie.com/auth/admin 으로 사용하는것 이로 인해 한정된 자원으로 리소스에 접근이 가능
      • 한정된 인터페이스란? GET, POST, PUT, DELETE 의 메서드를 의미 4가지 인터페이스로 한정지어 하나의 URI로 많은 동작을 수행할 수 있습니다.
    • 무상태성(Stateless) : 작업을 위한 상태 정보를 저장하지 않음
    • 캐시 가능 : REST는 HTTP 를 그대로 사용하기 때문에 캐시 기능도 사용 가능 
    • 자체 표현구조 : REST API 메세지만 보고도 어떤 동작인지 쉽게 이해할 수 있도록 함
    • Client-Server 구조 : 서버는 API 제공, 클라이언트는 사용자 인증이나 컨텍스트(세션, 로그인 정보)등을 직접 관리하는 구조로 역할이 분명하게 나눠짐 -> 개발해야할 내용이 명확하고 의존의 분리가 잘 이루어짐
    • 계층형 구조 : REST 서버는 다중 계층으로 만들 수 있음. 보안, 로드 밸런싱, 암호화 계층으로 나눠 구조상의 유연성을 둘 수 있음
  • REST API 디자인 가이드
    • URI 는 정보의 자원을 찾아야합니다.
    • 자원에 대한 행위는 HTTP METHOD(GET, POST, PUT, DELETE)로 표현
    • 자원을 표현하는 Collection 과 Document
      • http:// restapi.example.com/sports/soccer/players/13
        • Collection : sports, players /
        • Document : soccer, 13

참고 자료

- REST API 제대로 알고 사용하기


[Java] Optional - 3

학습 내용 정리

  • Optional 은 단순히 null 대신 사용하기 위한것이 아님
  • "반환값이 없을 수도 있다" 를 나타내기 위함. 즉 "이 값은 없을 수도 있다" 라는 것
  • Optional 안에 있는 값을 얻기 위해서 ifPresent()-get() 보다는 orElse(), orElseGet(), orElseThrow() 를 사용하는 것이 더 낫다.
    • orElse() : Optional 값이 비어있을 때 실행할 행위를 정의할 수 있습니다.
    • orElseGet() : Optional 값이 비어있을 때 반환할 값을 지정할 수 있습니다.
    • orElseThrow() : Optional 값이 비어있을 때 발생시킬 예외를 정의할 수 있습니다.
  • Optional 은 필드로 사용할 목적으로 만들어진것이 아니므로 필드에 사용하지 않아야합니다.

참고 자료

- Java Optional 바르게 쓰기

'학습로그' 카테고리의 다른 글

[레벨2] 배포 미션 학습로그  (0) 2021.05.21
[레벨1] 블랙잭 학습로그  (0) 2021.04.27
[레벨1] 체스 학습로그  (0) 2021.03.26
학습 로그란?  (0) 2021.03.08
[레벨1]로또게임 학습로그  (0) 2021.02.26

댓글