1. 스프링 예제 프로젝트 Pet Clinic <프로젝트 설정>
프로젝트 클론, 빌드
$ git clone https://github.com/spring-projects/spring-petclinic.git
$ mvn package
애플리케이션 실행 (둘 중 선택)
- java -jar target/*.jar (빌드된 패키지를 실행시키는 명령)
ㄴ 이 프로젝트는 jar 프로젝트임. 어떻게 아냐면..
ㄴ pom.xml 에서 <packaging></packaging> 에 아무것도 지정하지 않으면 기본이 jar임.
- main 메서드 실행
ㄴ java application를 실행할 땐 반드시 maven package 를 수행해야함.
ㄴ 패키징 하면서 프론트 관련 lib를 생성하는 플러그인 이 있기 때문 -> 이 플러그인이 동작해야만 화면이 깨지지 않음
실행하면 tomcat 이 8080포트에 뜬 다는걸 로그로 알 수 있음 -> 웹 페이지 접속 가능
애플리케이션 종료 : ctrl +c
2. 스프링 예제 프로젝트 Pet Clinic <프로젝트 살펴보기>
프로젝트 구조: 평범한 Spring Boot + maven 프로젝트라고 볼 수 있다. (jmeter도 들어있네..)
ㄴ Spring Boot 기반 -> main 애플리케이션으로 실행해서 애플리케이션 띄울 수 있음
ㄴ 웹 application임에도 Java application을 띄울 수 있음. 내부적으로 내장 톰캣, 그 외 자동 설정이 동작하므로 많은걸 직접 설정하지 않아도 스프링 기반의 웹 애플리케이션을 빠르게 만들 수 있기 때문이다.
ㄴ Spring Boot에선 웹 application 뿐 아니라 많은 application 또한 개발 할 수 있음
로그 보기
ㄴ 로그 설정파일에서 로그 레벨 (기본 INFO) -> DEBUG로 변경
ㄴ Spring Boot 는 application.properties파일에서 변경 (logging.level.org.springframework.web = DEBUG)
ㄴ 해당 설정으로 dispatcherServlet이 초기화 됨 -> 인프런 스프링 mvc강좌 보기
로그 분석: 컨트롤러에서 반환하는 문자열은 뷰(resource하위경로)를 보여주는 것임 (이후 예시는 메모skip함)
ㄴ 뷰에서 tymleaf쓰네
디버깅
ㄴ 중단점 찍기: 호출하면 중단점에서 걸림.
프로젝트 분석 과제
- lastname -> firstname 으로 검색
- 해당 키워드를 “포함”하는 이름 검색
- owner에 age 추가
3. 스프링 예제 프로젝트 Pet Clinic <프로젝트 과제 풀이>
과제 풀이
1) lastname -> firstname
html에서 input받을 때 firstname으로 바인딩 받음.
컨트롤러에서도 firstname으로 사용하는 필드명 수정
OwnerRepository에서도 사용하는 메서들도 firstname으로 수정.
(@Query에서 사용하는 곳 수정)
2) 해당 키워드를 “포함”하는 이름 검색
@Query에서 “contain”의 조건으로 조회해야하므로 … LIKE %:firstName% 으로 수정한다.
%(와일드 카드)를 :(콜론) 앞에 추가해야하는 것 주의
3) owner도메인에에 age 필드 추가
도메인에 필드, getter/setter 추가
->> 항상 에러 메시지를 읽으세요….
ㄴ user라는 테이블에 age라는 컬럼이 없다는 뜻 -> schema.sql에 직접 추가.
ㄴ data.sql에 insert into owners 에 age 값 추가
뷰에도 Add Owner의 form에 나이 필드 추가
ㄴ Owner List(조회)에도 추가
4. 스프링 IoC <스프링 IoC>
Inversion of Control 제어권의 역전 (자세한건 마틴 파울러의 글 읽어보기)
- 일반적인 제어권: “내가 사용할 의존성은 내가 만든다.”
class TrialController{
private TrialRepository repo = new TrialRepository(); // 직접 new로 인스턴스를 만들었습니다.
}
- IoC: “내가 사용할 의존성을 누군가 알아서 주겠지”
- 내가 사용할 의존성의 타입(또는 interface)만 맞으면 다른 인스턴스들 중 어떤거든 상관없음
- 그래야 내 코드 테스트 하기도 편하지
class TrialController{
private TrialRepository repo;
public TrialController(TrialRepository repo){ // 외부(아래 테스트코드)에서 TrialRepository를 넣어줍니다.
this.repo = repo;
}
}
class TrialControllerTest{
@Test
public void create(){
TrialRepository repo = new TrialRespository();
TrialController controller = new TrialController(repo);
}
}
IoC 예제 코드 리뷰) 컨트롤러 내부에 TrialRepository를 인자로 받는 생성자가 없다면?
ㄴ repo를 사용할 때 NPE발생한다. 인스턴스를 만들어서 넣어줘야한다.
ㄴ 그럼 누가 인스턴스화해줘서 넣어주냐? 위 예제에서 인스턴스 하는 코드는 없는데? -> 스프링 IoC 컨테이너가 해준다~
ㄴ 컨트롤러 생성자가 repository를 인자로 받는 생성자 하나뿐이라 해당 repository 없이는 컨트롤러 인스턴스를 못만들게 돼있음 -> TrialRepository가 인스턴스화되지 않을 일(NPE발생)이 없어 코드가 안전해짐.
junitTest에서 컨트롤러 테스트 할 땐
public class TrialControllerClass {
@MockBean
private TrialRepository repo;
//..
}
ㄴ repository를 @MockBean으로 만들어서 넣어줬다. -> 이 타입의 인스턴스를 스프링이 테스트를 만들때 자동으로 만들어주고 빈으로 등록함.
ㄴ 빈(Bean): 스프링이 관리하는 객체
ㄴ 그래서 테스트코드에서 컨트롤러 만들때도 repository의 빈을 가져와 주입해준다. -> 누가? 스프링에 있는 IoC 컨테이너가!
ㄴ 즉, 스프링은 빈들의 의존성을 관리하고 빈을 등록(스프링 컨테이너 안에 있으니 빈이라고 부름)하고, 필요한 의존성을 서로 주입해준다. 등록, 주입하는 방법은 다양하다!!
이번 수업 DI(dependency Injection)에 대한 예제 코드 봄
ㄴ 반드시 스프링이 필요한건 아님
ㄴ 우리가 직접 만들어서 주입할수도 있지만
ㄴ Spring Framework 이 제공하는 풍부한 DI관련 기능 , 컨테이너의 lifecycle 인터페이스를 통한 다양한 확장이 가능하므로 Spring Framework을 많이 사용하는 것임.
'Spring Boot' 카테고리의 다른 글
인프런 - 예제로 배우는 스프링 입문 (개정판) 정리(3) (0) | 2021.06.06 |
---|---|
인프런 - 예제로 배우는 스프링 입문 (개정판) 정리(2) (0) | 2021.06.06 |
댓글