course/inflearn

[스프링 입문]

hjkim0502 2022. 7. 29. 01:02

스프링 웹 개발 기초

  • 정적 컨텐츠: 관련 컨트롤러가 없어 바로 관련 html을 클라이언트에 넘겨줌 (우선순위 최하위)
  • MVC: 컨트롤러가 (사용자에게 데이터를 받고) 모델에 처리한 후 뷰 리솔버가 이를 반영한 html을 클라에 넘겨줌
  • API: 컨트롤러가 (사용자에게 데이터를 받고) 이를 넘겨받은 HttpMessageConverter가 문자나 객체를 http body에 직접 넣어 클라에 보내줌

 

일반적인 웹 애플리케이션 계층 구조

테스트 케이스 작성 (단위 테스트)

  • main 메소드나 컨트롤러에서 눈으로 보는 테스트보다 테스트 파일을 따로 만들어 프레임워크를 활용하기
  • 테스트 순서에 의존관계가 있지 않게 @AfterEach로 db 초기화, @BeforeEach로 객체 새로 생성 및 DI
  • Assertions.assertThat (assertj) -> isEqualTo
  • Assertions (junit) -> assertThrows (안되는 케이스일 때), assertEquals
  • given -> when -> then 순으로 테스트 짜기

 

스프링 빈과 의존관계

1. 자동 등록

  • @Component (하위 @Controller, @Service, @Repository도 마찬가지) 를 객체위에 지정하면 빈으로 자동 등록
  • 해당 객체 생성자 위에 @Autowired하고 인자로 주입 받을 객체 명시하면 객체 생성 시점에 의존관계 자동 주입
    • 생성자 1개일 시 @Autowired 생략 가능
    • 빈으로 등록된 객체에 대해서만 주입해줌 (직접 생성한 객체에서는 동작하지 않음)
  • 스프링이 컨테이너에 빈 등록 시 기본값은 싱글톤(유일하게 하나 등록하여 공유)

2. 직접 등록

  • Config 클래스 생성해 @Configuration 애노테이션 붙힘
  • 빈으로 등록할 이름으로 각 메소드에 @Bean 붙힘
  • 필드 주입, setter 주입, 생성자 주입
// 생성자 주입
@Configuration
public class SpringConfig {
    @Bean
    public MemberService memberService() {
    	return new MemberService(memberRepository());
    }
    @Bean
    public MemberRepository memberRepository() {
    	return new MemoryMemberRepository();
    }
}
  • 실무에서는 주로 정형화된 객체에는 자동 등록 사용
  • 정형화되지 않거나, 상황에 따라 구현 클래스 변경해야하면 직접 등록 사용

 

스프링 DB 접근 기술

1. 순수 Jdbc: 스프링이 DataSource(DB 커넥션 획득 시 사용하는 객체)를 빈으로 등록해 DI 받을 수 있음

* 매우 반복이 심하고 SQL도 작성해야함

  • 스프링 통합 테스트
  • @SpringBootTest: 스프링 컨테이너와 함께 테스트 실행
  • @Transactional: 테스트 시작 전에 트랜잭션 시작, 완료 후 항상 롤백 -> 테스트끼리 의존하지 않게 함

2. 스프링 JdbcTemplate: 순수 jdbc와 마찬가지

* 반복은 많이 줄었지만 SQL은 직접 작성

 

3. JPA: EntityManager 활용, JPA 엔티티 매핑 -> 서비스 계층 트랜잭션 추가 (모든 데이터 변경은 트랜잭션 안에서)

* 반복 코드와 기본적인 SQL도 JPA가 직접 만들어서 실행해줌 (JPQL활용) -> 생산성 향상 

 

4. 스프링 데이터 JPA: JPA를 편리하게 사용하게 도와주어 핵심 비즈니스 로직에 집중할 수 있게 함

* 코드 한 줄

 

앞서 DI를 잘 활용했기에 Config 클래스에서만 코드를 살짝 수정하면 구현 클래스 쉽게 변경 가능

// SpringConfig에서 DB 갈아끼우기
@Bean
public MemberRepository memberRepository() {
// return new MemoryMemberRepository();
// return new JdbcMemberRepository(dataSource);
// return new JdbcTemplateMemberRepository(dataSource);
// return new JpaMemberRepository(em);
return new MemberService(memberRepository);
}
  • 실무에서는 기본(JPA + 스프링 데이터 JPA) + 복잡한 동적 쿼리(Querydsl) (+ JdbcTemplate)

 

AOP(Aspect Oriented Programming)

예) 모든 메소드의 호출 시간 측정(공통 관심 사항)

  • 각 메소드에 구현 시 시간 측정 로직과 핵심 로직이 섞여 지저분하고 유지보수 어려움
  • AOP적용하면 별도의 로직으로 만들어 코드도 간결하며 유지보수도 좋고 원하는 적용대상 지정 가능
  • 동작 방식: 프록시 객체 주입

 

출처: https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8/