일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 의존관계 자동 주입
- Controller
- 테스트 코드
- ResponseEntity
- RunWith
- entity
- Not Acceptable
- 406 NOT_ACCEPTABLE
- 스프링 컨테이너
- Java Reflection API
- 키움
- 405 METHOD_NOT_ALLOWED
- jdbc template
- testresttemplate
- 기본 생성자
- 컴포넌트 스캔
- 의존성 주입
- 스프링
- 랜덤 포트
- 스프링 데이터 JPA
- 빈 스코프
- JPA
- jdbc
- restTemplate
- 통합 테스트
- 가을야구
- 스프링 IoC 컨테이너
- SpringBootTest
- 좋은 객체지향 설계 원칙
- 정적 컨텐츠
- Today
- Total
코드네임 JY
[스프링 입문] 스프링 빈과 의존관계 본문
미리보기
✅ 스프링 빈이란 무엇인가!
✅ 스프링 IoC 컨테이너가 하는 역할은 무엇인가!
✅ 스프링 빈 등록 방법에 대해 알아보자!
🍕 스프링 빈 (Spring Bean)
스프링 (IoC) 컨테이너에 의해 관리되는 자바 객체
라고 정의하는데, 객체는 코딩하는 사람이 직접 생성하고 관리할 수 있는거 아닌가? 라는 생각이 든다.
맞다. 보통 자바에서는 우리가 직접 클래스의 객체를 생성하고, 해당 인스턴스를 활용하도록 코드를 작성할 수 있다.
해당 객체를 사용해야하는 클래스가 여러 개라면, 각 클래스마다 매번 새롭게 객체를 생성해서 사용할 수도 있다.
하지만, 하나의 객체를 여러 개의 클래스에서 여러 번 정의하는 것은 조금 찝찝하기도 하고.. 관리하기도 쉽지 않을 것이다.
여기서 드는 생각!! 하나의 객체 인스턴스로 전체 코드에 적용할 수는 없을까?
🌮 IoC 컨테이너와 의존성 주입
실생활에서 '컨테이너(Container)'는 필요한 물건들을 담는 하나의 박스 같은 느낌으로 생각할 수 있다.
이 개념은 스프링에서도 사용된다. 스프링에서는 객체를 담아야하는데, 이 객체를 담고 있는 부분을 컨테이너라고 할 수 있다!
개발자는 객체의 생성 및 호출을 직접 코드로 작성할 수 있는데, 객체의 생성 및 호출 권한을 컨테이너에게 위임할 수도 있다.
이는 일반적인 과정과 달라 '제어의 역전' 이라고 부르며, 이를 담당하는 컨테이너를 바로 'IoC 컨테이너' 라고 한다!
(참고 : 'IoC' 는 'Inversion of Control' 을 의미한다)
'일반적으로 자바에서 객체를 사용하는 과정'과 'IoC 컨테이너에게 이를 위임하는 것'은 위와 같이 비교할 수 있다.
객체를 생성했다면 서로 의존성을 주입해주어야 하는데, 이를 '의존성 주입(Dependency Injection)' 이라고 부른다!
(의존성 주입에는 크게 3가지 방식이 있는데, 아래 내용까지 설명하고 나열하겠다.)
🎯 참고 : 의존성 주입을 활용하면, 스프링 내에서 더 많은 기능들을 사용할 수 있다! (예시 : AOP ← 추후 포스팅 예정)
🥨 스프링 빈 등록 방법
스프링 빈을 등록하는 방법에는 2가지 방법이 있다.
컴포넌트 스캔과 자바 코드로 직접 등록하는 방법이 있다.
컴포넌트 스캔
스프링 백엔드에서 Controller ↔ Service ↔ Repository로 이어지는 구조를 사용한다고 했는데, 각각의 어노테이션이 존재한다.
컨트롤러 역할을 하는 클래스에는 @Controller
비즈니스 로직을 담당하는 클래스에는 @Service
저장소를 활용을 담당하는 클래스에는 @Repository 어노테이션을 각각 붙일 수 있다!!
하지만 이는 @Component 라는 어노테이션이 다 포함하고 있는 구조로 되어 있다.
따라서 각각 이름을 붙여도 되고, 아니면 한 번에 @Component 어노테이션을 사용해도 된다.
스프링이 서버에서 동작하기 시작할 때, @Component 어노테이션과 관련된 클래스들이 있으면 (Controller, Service, Repository)
이들의 객체를 하나씩 생성해서 스프링 IoC 컨테이너에 등록을 해놓는다. 그러면 이들의 연관관계를 설정해주어야 하는데,
그 관계들을 연결시켜주는 것이 바로 @Autowired 어노테이션이다!!
@Controller
public class MemberController {
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
}
@Service
public class MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
각 클래스마다 @Controller, @Service, @Repository 이 달려있다면, @Autowired 를 통해서 이들의 관계를 묶어준다는 것이다!!
그리고 위에서 설명한 @Autowired 어노테이션을 활용해 연관관계를 이어주는 것이 바로 '의존성 주입(DI)' 라고 할 수 있는데,
의존성 주입 방식에도 크게 3가지 방법이 있다.
/* 1. 생성자 주입 */
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
/* 2. 필드 주입 */
@Autowired final MemberService memberService;
/* 3. Setter 주입 */
@Autowired
public void setMemberSerivce(MemberService memberService) {
this.memberService = memberService;
}
하지만 되도록이면 생성자 주입 방식을 사용하는 것을 추천한다!
자바 코드로 직접 등록
@Configuration
public class SpringConfig {
@Bean
public MemberService memberService() {
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemberRepository();
}
}
이는 자바 코드를 사용해서 수동으로 스프링 IoC 컨테이너에 빈을 등록할 수 있다. ('빈 == 객체' 라고 생각하면 된다!)
설정 클래스임을 알려주는 어노테이션은 @Configuration 이고, @Bean 을 사용해 각 메소드마다 빈을 등록할 수 있다.
일단 이 코드를 사용하려면 @Component 와 관련된 어노테이션을 지우고 진행해야한다.
개인적으로 컴포넌트 스캔방식이 더 직관적이라고 느끼는데, 코드로 직접 작성하는 방식의 장점이라면..
예를 들어 Repository를 변경하고 싶을 때, 컴포넌트 스캔은 해당 Repository에 가서 관련 어노테이션을 모두 변경해주어야하지만,
위 방식에서는 @Bean이 달린 Repository 관련 메소드의 return 부분을 새로운 클래스 이름으로 대체하면 된다!!
정리하면, 조금 더 변경에 용의하다는 것이다!! (리포지토리를 갈아끼우고 싶을 때와 같은 경우)
정리
'스프링 IoC 컨테이너' 는 스프링에서 사용되는 객체를 담을 수 있다.
이러한 스프링 IoC 컨테이너에 의해 관리되는 자바 객체를 '스프링 빈' 이라고 한다.
스프링이 서버에서 시작될 때, 스프링은 @Component 와 관련된 클래스들을 객체로 만들어서 스프링 IoC 컨테이너에 올려놓는다.
컨테이너에 올려진 객체들의 연관관계는 @Autowired 를 활용해 스프링이 직접 의존성 주입(Dependency Injection) 해준다.
하지만 코딩하는 사람이 이러한 연관관계를 직접 자바 코드로 작성할 수도 있다! 이는 조금 더 클래스 변경에 용의하다!
'백엔드 공부' 카테고리의 다른 글
[스프링 입문] JPA & 스프링 데이터 JPA (0) | 2022.12.14 |
---|---|
[스프링 입문] JDBC & JDBC Template (0) | 2022.12.14 |
[스프링 입문] 테스트 코드 (0) | 2022.12.06 |
[스프링 입문] Controller, Service, Repository (0) | 2022.12.06 |
[스프링 입문] API (0) | 2022.12.05 |