Spring(Web)

Spring 완전정복 - 5 / 스프링 빈과 의존관계

kjy0349 2022. 4. 20. 18:47

Spring 컨테이너를 이용해, Controller - Service - Repository를 싱글톤으로 사용 할 수 있는 방법을 배웠다.

기본적으로

1. 컴포넌트 스캔 방식으로, 스프링이 자동으로 컨테이너에 넣음

2. 설정 파일을 만들어, 수동으로 의존관계를 설정

총 두 가지 방법이 있다.

컴포넌트 스캔

첫 번째로, 컴포넌트 스캔 방식은 그저 이어줄 클래스들위에 @Component 어노테이션을 추가해주기만 하면 스프링이 자동으로 컨테이너에 등록해주는 방식이다. 다만 @Service나 @Repository와 같이 특수한 컴포넌트 어노테이션들이 있는데, 각 클래스들의 역할 별로 특수한 컴포넌트 어노테이션을 적용해줘도 잘 작동했다.

@Controller
public class MemberController {
    private final MemberService memberService;

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

컨트롤러에서 서비스를 가져와 사용하려면 new 키워드를 이용해 새로 객체를 만들어서 사용해야하는데, 위 코드와 같이 @Autowired 어노테이션을 사용하면 컨트롤러에서 객체를 새로 생성하게되어 서비스 객체가 여러개 생성되는 등의 낭비 없이 싱글톤으로 한 개의 객체만 사용 할 수 있게된다.

@Service
public class MemberService {

    private final MemberRepository memberRepository;

    public MemberService(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }
@Repository
public class MemoryMemberRepository implements MemberRepository {

    private static Map<Long, Member> store = new HashMap<>();
    private static long sequence = 0L;

위 코드들과 같이 각각 사용 할 Service, Repository 클래스에 각각 어노테이션들을 추가해주면, 스프링 부트가 실행될 때 미리 만들어두었던 객체들이(어노테이션을 써두면 서버가 올라올 때, 스프링 컨테이너에 해당 객체들이 하나씩 만들어져있음.)
해당 컨트롤러로 넘어와 사용 할 수 있게 되는것이다.

설정 파일을 통한 수동 연결

위 그림과 같이 메인 패키지 하위에 SpringConfig라는 클래스를 만들어준 후, @Configuration 어노테이션을 써두어 설정용 클래스임을 알려주면 서버가 올라올 때 해당 클래스들을 객체로 만든 후 스프링 컨테이너에 넣어두게 된다.

package hello.hellospring;

import hello.hellospring.repository.MemberRepository;
import hello.hellospring.repository.MemoryMemberRepository;
import hello.hellospring.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();
    }
}

이렇게 Bean 어노테이션을 적어두면, 스프링 컨테이너에 객체가 만들어져있게 된다. 컨트롤러에서는 컴포넌트 스캔 방식과 다르게, 굳이 Autowired 어노테이션을 써두지 않아도 알아서 스프링 컨테이너에서 잘 갖고와 쓰는듯 하다.