콘텐츠로 이동

2021 04 17

2021-04-17

build.gradle

  • 버전 설정, 라이브러리 땡겨오기
  • sourceCompatibility = 자바 버전
  • dependencies = 라이브러리 가져올 것
  • repositories = 라이브러리를 가져오는 "그 어디"
  • 의존관계가 필요한 라이브러리들 쭉 다 땡겨옴!

스프링에 필요한 라이브러리

  • 스프링 부트 라이브러리 - spring-boot-starter-web - spring-boot-starter-tomcat: 톰캣(웹서버) - spring-webmvc: 스프링 웹 MVC - spring-boot-starter-thymeleaf: 타임리프 템플릿 엔진 - spring-boot-starter: 스프링 부트 + 스프링 코어 + 로깅 - spring-boot - spring-core - spring-boot-starter-logging - logback, slf4j
  • 테스트 라이브러리 - spring-boot-starter-test - junit: 테스트 프레임워크 - mockito: 목 라이브러리 - assertj: 테스트 코드 작성 라이브러리 - spring-test: 스프링 통합 테스트 지원

컨트롤러

  • 컨트롤러에서 리턴값으로 리턴 값으로 문자를 반환하면, 'viewResolver'가 화면을 찾아서 처리 - 스프링 부트 템플릿엔진 기본 viewName 매핑 - 'resources:template/' + {viewName} = '.html'

리눅스에서 빌드하기

  • ./grqdlew build
  • cd build/libs
  • java -jar hello-spring-0.0.1-SNAPSHOT.jar

스프링 웹 개발 기초

  • 정적 컨텐츠 - 그냥 HTML 파일 웹브라우저에게 주기 - localhost:8080/hello-static.html ==> 바로 정적 컨텐츠 접근/반환 가능 - 요청 옴 -> 톰캣 내장 서버가 받음 -> hello-static 관련 컨트롤러 로직 확인 -> 없으면 resource 뒤져봄 -> 반환
  • MVC와 템플릿 엔진 - HTML을 서버에서 동적으로 바꿔서 주기 - Model/View/Controller - 관심사 분리, 역할/책임 분리 - View는 화면 그리는데 집중 - Controller, Model은 비즈니스 로직, 내부 처리에 집중 - Thymeleaf등의 템플릿 엔진으로 처리한 HTML 파일 변환 후 클라이언트에게 리턴
  • API - JSON이라는 데이터 포맷으로 리턴해주기 - SPA와 궁합이 좋음 - 서버끼리의 통신도 좋음 - @ResponseBody를 사용해 객체를... - 리턴 타입이 문자열이네? text/html 형식으로 반환해야 겠다~ 문자열로! - 리턴 타입이 객체네? application/json 형식으로 반환해야겠다! - @ResponseBody를 만나면 - HttpMessageConverter 실행 - 클라이언트의 HTTP Accept 헤더와 서버의 컨트롤러 반환 타입 정보를 합쳐 알맞은 HttpMessageConverter가 실행됨 - 리턴타입 String... StringConverter 실행 - StringHttpMessageConverter - 리턴타입 Object... JsonConverter 실행 - MappingJackson2HttpMessageConverter

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

 Controller --> Service --> Repository --> DB
            \       |      /   
             --> Domain <--
  • Controller: 웹 MVC의 컨트롤러 역할
  • Service: 핵심 비즈니스 로직 구현
  • Repository: DB 접근, Domain 객체를 DB에 저장하고 관리
  • Domain: 비즈니스 도메인 객체, 예) 회원/주문/쿠폰 등 주로 DB에 저장되고 관리 됨

스프링 빈과 의존관계

  • 스프링 빈을 등록하는 2가지 방법 - Component Scan & 자동 의존관계 설정 - @SpringBootApplication을 실행하는 클래스가 속한 패키지의 하위에서 Component Scan 해줌 - 스프링은 스프링 컨테이너에 스프링 빈을 등록할 때, 기본으로 싱글톤으로 등록한다. - 따라서, 같은 스프링 빈이면 모두 같은 인스턴스이다 - Component Scan ==> @Component(@Repository/@Service/@Controller) - @AutoWired 자동 의존 관계 설정

    - 자바 코드로 직접 스프링 빈 등록하기 - @Configuration을 Class에 추가하여 직접 스프링 빈을 등록할 수 있음

    @Configuration
    public class SpringConfig {
        @Bean
        public MemberService memberService() {
            return new MemberService(memberRepository());
        }
    
        @Bean
        public MemberRepository memberRepository() {
            return new MemoryMemberRepository();
        }   
    }
    

  • DI는 생성자 주입, 필드 주입 (인스턴스 변수에 @Autowired 추가), Setter 주입으로 가능 - 생성자 주입으로 불변성 보장하도록 해보자

스프링 DB

  • generated by default as identity
  • DataSource
  • DB 접근 방식을 인터페이스로 정의 - 기존 MemoryMemberRepository 클래스에서 사용하던 것을, - JdbcMemberRepository 라는 클래스를 만들어서 확장 - 둘 다 MemberRepository 인터페이스의 구현체 - Dependency Injection으로 OCP 원칙을 잘 구현한 코드 설정가능 - 조립! 조립!
  • @SpringBootTest - spring 컨테이너와 함께 테스트를 실행한다
  • @Transactional - AutoCommit vs commit - insert + commit 까지 해야 반영됨 - test 후 RollBack? - 테스트 케이스에 이 어노테이션이 남아있다면, 테스트 시작 전에 트랜잭션을 시작하고, 테스트 완료 후에 항상 롤백 - 이렇게 하면 DB에 데이터가 안남아서, 다음 테스트에 영향 XX
  • 단위 테스트 VS 통합 테스트 - 단위 테스트 - 빠르다! - 우선 통합테스트를 작성해놓으니... - @Configuration 에서 Repository로 사용할 Bean 객체를 변경해주었더니 해당 클래스에 대한 DB 테스트가 촤르르 진행됨 - 편하다!
  • 스프링 JdbcTemplate - JDBC API 중 반복 코드를 제거해줌 - SQL은 직접 작성하자 - MyBatis?
  • JPA - 기존의 DB 접근 방식은 결국 개발자가 SQL 썼어야 했어! - JPA로 전환하면, SQL과 데이터 중심의 설계에서 객체 중심의 설계로 패러다임 전환이 가능 - 개발 생산성 UP! - ORM 기술! - Object <-> Relational DB Mapping! - hibernate?
  • 스프링 데이터 JPA - 리포지토리에 구현 클래스 없이 인터페이스 만으로 개발이 가능?! - CRUD 기능도 스프링 데이터 JPA가 제공 - 관계형 DB 사용한다면, 스프링 데이터 JPA 사용이 필수! - 인터페이스만으로 개발 끝! - 비슷한 로직은 다 알아서 SQL문 생성해서 쿼리 날려줌!

AOP

  • AOP가 필요한 상황 - 모든 메서드의 호출시간 측정? - 공통 관심 사항 vs 핵심 관심 사항
  • Aspect Oriented Programming - 관점 지향 프로그래밍? - 핵심 관심 사항 분리! - 어디에서 병목이 발생할까요??!! - 호출이 될 디렉토리들을 지정해서 해당 디렉토리에서 실행해줌
  • 핵심 관심 사항을 원하는 적용 대상에게 깔끔하게 수행시킬 수 있음
  • Proxy...?