* 인프런 김영한 강사님의 스프링 입문 강의 정리
회원 컨트롤러가 회원 서비스와 리포지토리를 사용할 수 있으려면
그들 사이를 엮어주는 무언가가 필요하고
이 때 사용하는 것이 바로 스프링 빈이다.
스프링 빈을 등록하는 방법은 컴포넌트 스캔과 직접 코드로 등록하는 두 가지 방법이 있다.
1. 컴포넌트 스캔
- 컴포넌트 스캔은 @Component 어노테이션이 있으면 스프링 빈으로 자동 등록된다.
- @Controller, @Service, @Repository 등은 @Component를 포함하므로 스프링 빈으로 자동 등록된다.
[controller]
@Controller
public class MemberController {
...
}
[service]
@Service
public class MemberService {
...
}
[repository]
@Repository
public class memoryMemberRepository implements memberRepository{
...
}
2. 직접 스프링 빈 등록
직접 코드로 스프링 빈을 등록할 시에는 컴포넌트 스캔 시 사용했던 어노테이션을 제거해야한다.
다음과 같이 SpringConfig 파일을 만들고 @Configuration 어노테이션을 사용한다.
그리고 @Bean 어노테이션으로 회원 서비스, 회원 리포지토리를 각각 스프링 빈에 등록한다.
스프링 빈을 직접 구현하면 상황에 따라 구현 클래스를 변경할 때
SpringConfig 파일에서 관리가 가능하다.
따라서 예제에서는 현재 db설정을 하지 않았고 이후 설정한 db로 리포지토리를 변경해야 하기 때문에
컴포넌트 스캔 대신 자바 코드로 스프링 빈을 등록한다.
package myStudyspring.myStudyspring;
import myStudyspring.myStudyspring.repository.memberRepository;
import myStudyspring.myStudyspring.repository.memoryMemberRepository;
import myStudyspring.myStudyspring.service.MemberService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringConfig {
@Bean
public MemberService memberService(){
return new MemberService(memberRepository());
}
@Bean
public memberRepository memberRepository(){
return new memoryMemberRepository();
}
}
스프링은 스프링 빈을 등록할 때 싱글톤으로 등록한다.
같은 스프링 빈을 사용한다면 같은 인스턴스이다.
싱글톤?
- 객체의 인스턴스가 오직 1개만 생성되는 패턴
- 메모리 낭비를 방지하고 데이터 공유에 용이하다.
- 동시성 문제, 테스트 어려움 등의 문제가 있다.
(프레임 워크의 도움을 받으면 보완 가능하다.)
스프링 빈이 생성되면 의존성을 주입해야 한다.
스프링 빈으로 등록한 후
@Autowired 어노테이션을 사용하면 스프링이 관련 객체를 찾아 의존성을 주입(DI: Dependency Injection)한다.
@Controller
public class MemberController {
//new로 객체를 생성할 필요 없이 스프링 컨테이너에서 가져다 쓰면 된다.
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
}
DI에는
1. 필드 주입
2. setter 주입
3. 생성자 주입
의 3가지 방법이 있다.
[필드 주입]
- 중간에 변경이 어려우므로 권장 x
@Controller
public class MemberController {
//필드 주입
@AutoWried
private MemberService memberService;
}
[setter 주입]
- public 으로 열려있어야 하므로 누구나 호출 가능하여 노출될 위험이 있다.
- 호출하지 않아도 될 메서드를 호출할 가능성이 있다.
- 권장 x
@Controller
public class MemberController {
//세터 주입
private MemberService memberService;
@Autowired
public void setMemberService(MemberService memberService) {
this.memberService = memberService;
}
}
[생성자 주입]
- 의존 관계가 실행 중 동적으로 변하지 않으므로 권장
@Controller
public class MemberController {
//생성자 주입
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
}
실무 프로젝트를 경험할 당시
어떤 분은 필드 주입을 사용하고 어떤 분은 생성자 주입을 사용하였다.
그 둘의 차이에 대하여 명확하게 이해가 가지 않았는데
이번 학습을 통해 필드 주입과 세터주입 그리고 생성자 주입을 구분하고 장단점을 알게 되었다.
어떤 코드가 좋은 코드인지 하나 하나 배워 가는 것 같다.
'컴퓨터 > Spring Boot' 카테고리의 다른 글
[TIL] Spring Boot(intellij) - [DB-1] H2 데이터베이스 설치 (0) | 2023.06.01 |
---|---|
[TIL] Spring Boot(intellij) - 홈 화면, 회원 등록, 조회 개발 (0) | 2023.05.30 |
[TIL] Spring Boot(intellij) - 회원 관리 개발(2) - 테스트 구현 (0) | 2023.05.25 |
[TIL] Spring Boot(intellij) - 회원 관리 개발(1) (0) | 2023.05.25 |
[TIL] Spring Boot(intellij) - 템플릿 엔진과 API (0) | 2023.05.24 |