BugDIARY
[SpringBoot] 스프링 빈 의존 등 정리 본문
이 글은 나중에 프로젝트를 생성할 경우 참고하기 위한 글입니다.
또한 김영한님의 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술을 학습한 내용입니다.
[Service]
- 통상적으로 비즈니스 로직을 주로 처리한다.
- validate체크는 메서드화 해주는 것이 좋다.
- Optinal로 반환되는 경우 따로 변수에 저장하는 것 보다는 바로 ifPresent같은것을 이용해 값을 체크하는 식으로 많이 사용한다.
[Repository]
- 기계적으로 개발스럽게 데이터를 넣고 빼는 작업을 주로 한다.
[테스트 코드 작성 규칙]
given, when, then
// given 뭔가가 주어졌을 때
// when 이것을 실행했을 때
// then 결과가 이렇게 나와야 한다.
[스프링 빈과 의존관계]
- 화면을 연결하려면 Controller와 View 템플릿이 필요하다.
<예시>
Member Controller → MemberService → MemberRepository
MemberController는 데이터를 사용하려할 때 MemberService를 이용해 데이터에 접근할 수 있고 Service는 Repository를 이용해 데이터를 다루게 된다.
그리고 이러한 것들을 서로 의존하는 관계, 의존관계라고 한다.
아래는 예시의 의존관계 부분을 코드화 한 것이다.
MemberController.java
public class MemberController {
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
}
MemberService.java
public class MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
해당 코드처럼 객체의 의존관계를 주입시켜주는것을 의존성 주입이라고 한다.
[@Controller]
- Controller를 만든 뒤 어노테이션을 붙일 경우 겉보기엔 아무런 일이 벌어지지 않지만 내부적으로는 아래와 같이 움직이며 결과적으로 스프링은 컨테이너 안에 있는 것들을 관리하게 된다.
1. 스프링 컨테이너가 생성
2. @Controller어노테이션이 있는 Controller클래스의 객체를 스프링 컨테이너에 넣어줌
[Service]
- new를 생성해서 서비스를 사용하는 경우 관리가 어렵다. 하나의 컨트롤러만 Service를 사용하는 경우엔 문제가 없으나 두개의 컨트롤러에서 하나의 서비스를 호출할 때 마다 new를 계속해서 생성하여 Service에 등록하기 때문이다.
- @Service로 스프링 컨테이너에 등록하고 등록된 서비스를 가져다 쓰는것이 효율적이다.
- Service를 연결하는 것은 위의 MemberController.java를 참고할 것.
▷연결은 생성자를 @Autowired를 해주고 그 안에 service를 입력해주면 된다.
※ @Autowired만 사용할 경우 연결 되지 않는다. 이유는 스프링 컨테이너에 등록되지 않기 때문이다.
그러므로, @Autowired를 이용해 해당 서비스 혹은 리포지토리를 사용하려면 @Service, @Repository라는 어노테이션을 붙여 스프링 컨테이너에 등록 해야한다.
[정리]
▶Spring은 스프링 컨테이너를 생성하는데 그곳에 등록된 객체를 가져다 쓰는것이 일반적이다.
▶Controller에서도 Service나 Repository를 사용할 떄 컨테이너에서 가져다 쓰게 되는데 이때 @Service, @Repository처럼 어노테이션으로 정의를 해야 스프링 컨테이너에 빈으로서 등록이 된다.
▶ 컨트롤러에서 서비스나 리포지토리를 사용하려고 할 때 @Autowired어노테이션을 이용해 스프링 컨테이너에 등록된 객체를 불러오게 되고 이로서 서로 연결해서 사용할 수 있게 된다.
▶ 이것을 DI(Dependency Injection), 의존성 주입이라고 한다.
▶ 실제 현장에서는 컴포넌트 스캔을 사용하며, 정형화 되지 않거나 상황에 따라 구현 클래스로 변경하려 하면 설정을 변경해 스프링 빈으로 등록한다.
▶ @Autowired는 내가 직접 등록한 객체에서는 동작하지 않는다. 스프링 컨테이너에 올라가있는 컴포넌트에 한해서 동작한다. (Controller내부에서 new를 하거나 config로 직접 등록한 빈이 없을 경우 동작하지 않음.)
[스프링 빈 등록하는 2가지 방법]
1. 컨포넌트 스캔과 자동 의존관계 설정(@를 이용한 방식)
- @Component 어노테이션이 있으면 스프링 빈으로 자동 등록이 된다.
- @Controller 컨트롤러가 스프링 빈으로 자동 등록된 이유도 컴포넌트 스캔 때문이다.
- @Componen를 포함하는 다른 어노테이션들도 모두 빈에 등록된다.
- SpringApplication.run이 존재하는 곳의 하위 패키지들은 스프링이 스캔할 수 있으나 그곳에서 벗어난 패키지나 클래스들은 기본적으로는 스프링이 스캔할 수 없다.
- 스프링은 스프링 컨테이너에 스프링 빈을 등록할 때 기본으로 싱글톤(하나만 등록하여 공유한다.)으로 등록한다.
(설정으로 싱글톤이 아니게 개발할 수 있지만 기본적으론 싱글톤으로 사용한다.)
2. 자바 코드로 직접 스프링 빈 등록
- @Configuration어노테이션을 이용해 빈을 직접 등록할 수 있다.
@Configuration
public class SpringConfig{
@Bean
public MemberService memberService() {
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
// MemberRepository는 인터페이스로 작성하였기 때문에
// 해당 인터페이스를 Implements하고 있는 MemoryMemberRepository를 반환한다.
return new MemoryMemberRepository();
}
}
[DI주입 3가지]
- 생성자 주입
▷ 생성자를 통해 주입하는것
▷ 의존 관계가 서비스 실행 중에 바뀌는 경우는 거의 없으므로 생성자 주입을 추천한다.
(보통은 변경 사항이 생기면 서버를 내렸다가 다시올림)
- 필드 주입
▷ 생성자 빼고 필드에다가 @Autowired를 하는 것(변경이 힘들어 선호하지 않음)
- Setter주입
▷ 생성은 생성대로 되고, set을 통해 주입이 된다.
(단점 : public하게 노출이 되어 누군가 Service를 setService로 바꿀 수 있다.)
'IT > Java' 카테고리의 다른 글
증감 타이밍[메모] (1) | 2024.03.17 |
---|---|
[Spring Boot] 스프링 웹 개발 기초 방식 3가지 (0) | 2023.05.28 |
[SpringBoot]뷰 화면 연결 (0) | 2023.05.27 |
[SpringBoot]스프링부트 프로젝트 첫 시작 방법 (0) | 2023.05.19 |
[JAVA]커피 구매 내역 작성 및 확인 기능 만들기 (0) | 2021.09.24 |