[Spring 공부] 김영한님의 입문 강의 - 2
2022. 02. 16.
Spring Study
Spring Boot를 처음 공부하는 사람이 공부한 내용을 정리해서 작성한 포스트입니다. 오개념 및 오류가 있을 수 있으니, 발견하신다면 가감없이 댓글을 통해서 알려주세요! 확인하는 대로 정확한 정보를 확인해서 고치도록 하겠습니다.
개요
이번 Spring Boot 스터디는 배달의 민족의 김영한님께서 인프런에 올려주시는 자바 스프링 완전 정복 시리즈를 기반으로 진행한다. 그 시리즈의 가장 첫 강의인 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술을 들어보고 간단히 정리해보고자 한다.
해당 강의는 내가 느끼기에 크게 다음의 컨텐츠를 가지고 있었다.
- Spring 기초 기능 써보기
- Spring Bean과 의존 관계
- 회원 관리 예제 구현하기
- Controller - Service - Repository 패턴 적용
- Spring MVC 적용
- 위의 예제에 다양한 DB 접근 기술 적용
- JDBC
- JDBC Template
- JPA
- Spring Data JPA
- 위의 예제에 간단한 AOP 적용
이 포스트에서는 회원 관리 예제 구현하기에 대해서 정리해보도록 하겠다.
Spring Bean과 의존 관계
Spring Bean
Spring Bean은 Spring IoC 컨테이너에서 관리하는 자바 객체이다. 우리가 Spring Bean을 만들면 그것을 Spring 컨테이너에서 관리해주고, 우리가 그것을 필요로 할 때 직접 new
키워드로 만들어서 쓰는 것이 아니라 Spring이 관리하는 객체를 주입받아 사용하게 된다.
예를 들어 SampleController
라는 컨트롤러에서 SampleService
라는 서비스를 사용해야 한다고 하자. 그러면 Spring에서는 SampleController
에서 new SampleService();
를 통해 직접 SampleService
를 만들어 쓰는 것이 아니라, 다음과 같은 형태로 사용해야 한다.
@Controller
public class SampleController {
private final SampleService sampleService;
@Autowired
public SampleController(SampleService sampleService) {
this.sampleService = sampleService;
}
}
보면, SampleService
를 생성자의 인자로 전달받아서 그것을 인스턴스에 등록하여 사용하는 형태로 되어있다. 그러면 저 SampleService
를 전달해주는 함수(이를 테면 main
함수)는 어디 있는지 궁금할 수 있다. 놀랍게도, 필요가 없다! 생성자 위에 @Autowired
라는 어노테이션을 붙여두면 Spring이 구동되면서 연관된 객체를 컨테이너에서 찾아서 넣어준다. 이렇게 객체 의존관계를 외부에서 넣어주는 것을 DI(Dependency Injection), 의존성 주입이라고 한다.
그런데, Spring 컨테이너에서 연관된 객체를 찾아서 넣어준다고 했다. 그러면 당연히 Spring 컨테이너에 객체가 등록이 되어있어야 할 것이다. 다른 말로, 주입받고자 하는 객체가 Spring Bean이어야 한다. 이 Spring Bean을 등록하는 방법엔 2가지가 있다.
- 컴포넌트 스캔과 자동 의존 관계 설정
- SpringConfig로 직접 등록
하나씩 간략하게 알아보자.
컴포넌트 스캔과 자동 의존 관계 설정
Spring이 구동될 때, 컴포넌트라는 것들을 찾으면서 이것들을 Spring Bean으로 자동 등록한다. 즉, Spring Bean으로 특정 객체를 등록하고 싶다면 이것이 컴포넌트라는 것을 명시해두면 된다.
명시하는 방법은 아주 간단한데, 그냥 클래스 앞에 @Component
어노테이션을 붙이면 된다. @Controller
가 자동으로 Spring Bean으로 등록되는 이유도, @Controller
라는 어노테이션의 내부 구현에 @Component
가 포함되어 있기 때문이다.
@Controller
, @Service
, @Repository
이 3개의 어노테이션의 내부 구현에는 모두 @Component
가 포함되어 있기 때문에, 저 어노테이션이 붙어 있으면 자동으로 Spring Bean으로 등록된다.
참고로, Spring은 기본적으로 컨테이너에 Spring Bean을 등록할 때, 기본으로 싱글톤으로 등록한다. 하나의 인스턴스를 공유해서 돌려쓴다는 의미이다. 따라서 같은 Spring Bean이면 모두 같은 인스턴스이다. 설정을 통해서 싱글톤이 아니게 설정할 수 있지만, 정말 특별한 경우를 제외하면 대부분 싱글톤을 사용한다고 한다.
SpringConfig로 직접 등록
<이름>SpringBootApplication
클래스가 있는 경로에 SpringConfig
라는 파일을 생성하면, 스프링이 구동될 때 이 파일의 내용을 참조하여 설정을 적용한다.
예를 들어 SampleService
를 Spring Bean으로 등록하고 싶으면, SpringConfig
클래스에 다음과 같이 구현하면 된다.
@Configuration
public class SpringConfig {
@Bean
public SampleService sampleService() {
return new SampleService();
}
}
뭘 써야되지?
위의 두 가지 방법 중, 어떤 것을 사용하는 것이 나은 방안인지 고민이 들었다. 실무에서는 주로 정형화된, 어노테이션으로 제공되는 Controller, Service, Repository에는 컴포넌트 스캔을 사용한다고 한다. 그리고 정형화 되지 않거나 아니면 상황에 따라 인터페이스만 유지하고 구현 클래스를 변경해야 하는 상황에는 설정을 통해서 직접 Spring Bean으로 등록한다고 한다. 아무래도 이렇게 하는 편이 클래스들에 어노테이션을 붙였다 떼었다 하는 것보다 나을 것 같다.
다음은
다음 포스트에서는 회원 관리 예제를 만든 강의 내용에 대해 간략히 정리해보도록 하겠다.
끝.