Spring-스프링 빈과 의존 관계(컴포넌트 스캔과 자동 의존 관계 설정하기)

snowball moon·2023년 10월 9일
0

Spring-입문

목록 보기
13/14

스프링 빈 등록 & 의존 관계 설정

서비스를 통해 멤버가 가입할 수 있고 repository에 저장되고 꺼낼 수 있는 로직을 만들었는데 이런 것들을 Controller와 View template로 회원 가입과 결과를 HTML로 화면에 띄워주면 된다.
이제 MemberController가 필요한데 MemeberController가 MemberService를 통해 회원가입을 하고 데이터를 조회할 수 있다. 이런 것을 서로 의존 관계가 있다고 표현한다.

MemberController를 만들어준다.
여기까지 해 놓으면 기능은 아직 없지만 Spring 컨테이너가 처음 뜰 때 Spring 컨테이너가 생기는데 @Controller가 있으면 MemberController 객체를 생성해서 Spring에 넣어두고 관리를 한다.
이런 것을 Spring 컨테이너에서 Spring 빈이 관리된다고 표현한다.

전에 했던 helloController를 보면 SpringBoot안에 컨테이너와 내장 톰켓 서버가 있는데 @Controller라는 것이 있으면 Spring과 관련된 기능들이 동작한다.

MemberController도 마찬가지로 Spring 컨테이너에서 관리를 하게 되는데 new로 인스턴스를 생성하면 MemeberController 이외에도 다른 여러 Controller들이 멤버 서비스를 가져다 쓸 수 있게 된다.
new로 생성해서 들어가보면 별 기능이 없기 때문에 여러 개의 인스턴스를 생성할 필요가 없고 하나만 생성해서 공용으로 사용하면 된다.

@Controller
public class MemberController {

    private final MemberService memberService;

    @Autowired
    public MemberController(MemberService memberService) {
        this.memberService = memberService;
    }
}

생성자에 @Autowired라고 되어 있으면 Spring Container에 있는 MemberService를 가져다가 연결 시켜준다.
실행시켜 보면 MemberService를 찾을 수 없다고 뜨며 연결되어 있지 않은 상태이다.

MemberService는 순수한 자바 클래스라서 스프링이 관리할 수 있는 상태가 아니다. 이럴 때 @Service를 추가해주면 Spring이 Container에 MemberService를 등록해준다.

구현체로 가서 @Repository를 추가해주는데 Controller, Service, Repository는 컨트롤러를 통해 외부 요청을 받은 다음 서비스에서 비즈니스 로직을 만들고 리포지토리에 데이터를 저장하는 방식으로 매우 정형화된 패턴이다.

위의 그림에서 Controller와 Service를 연결해야 하는데 이때 Autowired를 사용했다.
생성자에서 이렇게 쓰면 멤버 컨트롤러가 생성될 때 스프링 빈에 등록되어 있는 멤버 서비스 객체를 가져다가 넣어주는데 이걸 Dependency Injection(의존 관계 주입)이라고 한다.

MemberService에도 @Autowired를 해주면 MemeberRepository가 필요하다는 것을 스프링이 알아서 컨테이너에 등록하면서 생성자를 호출하고 Container에는 MemberRepository를 넣어준다.
지금 같은 경우에는 구현체로 MemberRepository가 있기 때문에 서비스에 MemberRepository를 주입해준다.
이 과정을 통해 위와 같은 그림이 완성되는데 Controller, Service, Repository가 연결되었다.

메인 메서드를 실행해보면 잘 뜨기 때문에 스프링이 컨테이너를 만들 때 문제가 없었다는 의미이다.

"스프링 빈을 등록하는 2가지 방법"

1.컴포넌트 스캔과 자동 의존 관계 설정(@Controller, @Service, @Repository)
2.자바 코드로 직접 스프링 빈 등록하기

먼저 컴포넌트인 이유는 @Service안에 들어가보면 @Component도 등록되어 있다. (Controller,Repository도 마찬가지로 @Component가 들어가 있다.
업로드중..

이런 식으로 @Component가 있으면 스프링 객체를 하나씩 생산해서 컨테이너에 등록한다.
@Autowired는 연관 관계를 의미하고 연결해준다. MemberController가 MemeberService를 사용할 수 있도록 해주고 MemberService가 MemberRepository를 사용할 수 있도록 도와준다.

이렇게 컴포넌트 스캔과 자동 의존 관계를 설정하면 스프링 빈이 자동으로 등록된다.
웬만한 것들은 스프링 빈으로 등록해서 사용하는 것이 얻는 이점이 많다.

컴포넌트 스캔 원리
@Component 애노테이션이 있으면 스프링 빈으로 자동 등록된다.
@Controller 컨트롤러가 스프링 빈으로 자동 등록된 이유도 컴포넌트 스캔 때문이다.
@Component 를 포함하는 다음 애노테이션도 스프링 빈으로 자동 등록된다.
->@Controller, @Service, @Repository

참고: 스프링은 스프링 컨테이너에 스프링 빈을 등록할 때, 기본으로 싱글톤으로 등록한다(유일하게 하나만
등록해서 공유한다) 따라서 같은 스프링 빈이면 모두 같은 인스턴스다. 설정으로 싱글톤이 아니게 설정할 수
있지만, 특별한 경우를 제외하면 대부분 싱글톤을 사용한다.

여기서 싱글톤은 유일하게 하나만 등록하는 것이다. 예를 들어서 HelloController 하나, MemberService 하나, MemberRepository 하나 이렇게 하나씩만 등록해서 공유하는 것이다.

References

스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8

0개의 댓글