본문 바로가기
Back-End/Spring

[Spring] pet clinic - 스프링 대표 예제 프로젝트

by hongdor 2023. 4. 8.
728x90

1. Spring github - pet clinic

스프링 깃허브에 접속한다. (Spring · GitHub)

 

star순으로 정렬하면 4번째에 petclinic이 있다.
(GitHub - spring-projects/spring-petclinic: A sample Spring-based application
)

접속한다

 

 

2. Pet clinic 이란?

구글에 검색해보면

The Spring PetClinic Community (spring-petclinic.github.io) 에 PetClinic은
Spring stack을 어떻게 사용하는지 보여주기 위해 설계된 예제라고 나온다.

 

Spring Petclinic community github 에서 더 다양한 예제들을 볼 수 있다. (MSA로 구성하는 예제 등)

Spring Petclinic community · GitHub

 

3. Pet clinic 살펴보기

 

pet clinic의 read me에 나와있는 ppt를 통해 개요를 살펴본다

Spring Petclinic sample application - Speaker Deck

 

1. Pet clinic의 구조

아래와 같은 계층으로 구성되어 있다.

  • view (JSP or Thymeleaf + CSS, webjars, Dandelion)
  • controller (Spring @MVC annotations, Bean Validation)
  • service (@Cacheable, @Transactional)
  • repository(jdbs → JPA → Spring Data JPA)

 

2. 데이터 접근

  • web.xml에 bean profile을 설정하면 그에 맞는 구현체가 적용된다. (jdbc, jpa or spring-data-jpa)
  • findByPetId에 필요한 코드 수
    • Jdbc : 16줄
    • JpaVisitRepo : 6줄
    • SpringDataJps : 0줄 (메서드 이름으로 자동생성)

 

3. 캐싱

동물병원의 리스트는 ehcache 라이브러리를 사용하여 캐싱된다.

@Cacheable(value = "vets")
public Collection<Vet> findVets() throws DataAccessException {...}

vets라는 이름의 캐시가 남아있으면 메서드를 실행하지 않고 반환한다.

ehcache.xml과 tools-config.xml 설정 파일에 60초간 캐시가 유지되도록 되어있다.

 

 

4. 예외 처리

  • mvc-core-config.xml에 설정되어 있다
    • exception stacktrace의 로그를 남긴다
    • 에러 발생 시 WEB-INF/jsp/exception.jsp 로 이동시킨다.
      exception.jsp 페이지 안에 exception 코멘트를 남긴다.
  • 예외 처리 과정
    1. PetRepository가 RuntimeException을 던진다
    2. ClinicService에서 Transaction을 롤백한다. exception을 컨트롤러까지 전파
    3. PetController는 아무것도 하지 않는다.
    4. SimpleMappingExceptionResolver 가 페이지를 이동시킨다.

 

5. AOP

모든 Repository 메서드에 로그를 남기는 공통 로직을 추가하기 위해 AOP를 사용한다.

@Aspect
public class CallMonitoringAspect{
  @Around("within(@org.springframework.stereotype.Repository *)")
    public Object invoke(...) { ... }
}

 

 

6. View Resolvers

  • ContentNegotiatingViewResolver가 요청 url의 확장자 자료형 형식에 따라 다른 view resolver로 보낸다
    • vets.html, owners.html 같은 JSP File 요청→ InternalResourceViewResolver
    • vets.xml, pets/9/visits.atom 같은 Atom & XML 요청 → BeanNameVR

 

 

7. 화면의 data tables

jQuery Datatables와 Botstrap기반의 Dandelion 라이브러리 사용 Dandelion Project

 

 

8. Webjars

  • Maven으로 CSS, JS 라이브러리 가져옴
  • jquery, jquery-ui, bootstrap 등
  • pom.xml, Spring configuration, JSP에 설정코드 작성

 

 

4. Pet clinic 실행 해보기

intelliJ 기준으로 

java 17 이상을 세팅 후 실행하면

localhost:8080에서 위와 같이 샘플 프로젝트를 확인할 수 있다.

 

5. 살펴보기

 

코드 많기 때문에 코드를 직접 적기 보다
살펴보면서 눈에 띄는 특징들을 정리해봤다.

 

  • 패키지 구성
    • owner, vet 처럼 domain을 패키지 계층으로 사용
  • Entity
    • BaseEntity > Person > Owner 로 공통된 속성의 칼럼들은 상속받는다.
    • JPA 사용을 위해 @Column, @OneToMany, @JoinColumn, @OrderBy 등을 사용
    • 칼럼에 제약 조건 어노테이션 @NotEmpty, @Digits 등을 사용한다. (참고 : Jakarta Bean Validation specification)
    • 제약 조건이 복잡한 경우 Validator를 구현
    • ToString 메서드 오버라이딩 구현을 위해 ToStringCreator 클래스를 사용
  • Repository
    • 스프링 데이터 JPA를 사용
    • 쿼리 작성을 위해 Repository메서드에 @Query사용
    • 조회전용 메서드에 @Transactional(readOnly = true) 사용
    • Pageable pageable를 인자로 함께 받아 Page<Entity>로 반환하는 메서드 사용(Query에 distinct 작성 필요)
    • 캐싱이 필요한 경우 메서드에 @Cacheable 사용
  • Controller
    • @InitBinder, @ModelAttribute 를 붙인 메서드를 통해
      데이터 바인딩 전, 혹은 요청 처리전에 실행되는 공통로직 작성
  • Null 체크
    • 메서드에서 인자의 선제적 NullCheck 필요 시 Assert.notNull 사용

 

— 이하 테스트 관련 특징

 

  • 패키지 구성
    • owner, vet, service(utility) 처럼 도메인 기준으로 나눔
  • 테스트 종류
    • validator를 localValidatorFactoryBean으로 테스트(필드의 유효값 검증이 제대로 되는지)
    • Controller api 동작은 mockMvc로 repository를 mocking하여 테스트
    • utility 메서드는 assertThat, assertThrows로 결과값 테스트
    • Repository 계층은 real DB에 연결 후 rollback이 필요한 경우 @Transactional과 함께 테스트
    • @SpringBootTest를 사용
728x90

댓글