Spring/inflearn

컴포넌트 스캔과 자동 의존관계 설정

곽수진 2022. 8. 28. 21:56
반응형

package hello.hellospring.controller;

import hello.hellospring.domain.Member;
import hello.hellospring.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class MemberController {

    private final MemberService memberService;

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

▶ 생성자에 @Autowired가 있으면 스프링이 연관된 객체를 스프링 컨테이너에서 찾아서 넣어줌

    → DI(Dependency Injection, 의존성 주입)

 

 

★ 에러 발생 ★

Consider defining a bean of type 'hello.hellospring.service.MemberService' in your configuration.

▶ helloController는 스프링이 제공하는 컨트롤러여서 스프링 빈으로 자동 등록됨 → @Controller가 있으면 자동 등록

 

 

스프링 빈을 등록하는 2가지 방법
- 컴포넌트 스캔과 자동 의존관계 설정
- 자바 코드로 직접 스프링 빈 등록
@Component 애노테이션이 있으면 스프링 빈으로 자동 등록됨
→ @Controller가 스프링 빈으로 자동 등록된 이유도 컴포넌트 스캔 때문

 

package hello.hellospring.service;

import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemberRepository;
import hello.hellospring.repository.MemoryMemberRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
@Component
public class MemberService {

    private final MemberRepository memberRepository;

    @Autowired
    public MemberService(MemberRepository memberRepository){
        this.memberRepository = memberRepository;
    }

    // 회원가입
    public Long join(Member member){
        // 동일한 이름을 가진 중복 회원 방지
        validateDuplicateMember(member); // 중복 회원 검증

        memberRepository.save(member);
        return member.getId();
    }

    private void validateDuplicateMember(Member member) {
        memberRepository.findByName(member.getName())
            .ifPresent(m -> {
                throw new IllegalStateException("이미 존재하는 회원입니다.");
        });
    }

    // 전체 회원 조회
    public List<Member> findMembers(){
        return memberRepository.findAll();
    }

    public Optional<Member> findOne(Long memberId){
        return memberRepository.findById(memberId);
    }
}

▶ 생성자에 @Autowired를 사용하면 객체 생성 시점에 스프링 컨테이너에서 스프링 빈을 찾아 주입함

    → 생성자가 1개인 경우 @Autowired는 생략 가능

 

MemberRepository도 스프링 빈으로 등록됨

    → 스프링 컨테이너에 스프링 빈을 등록할 때 기본으로 싱글톤으로 등록(유일하게 하나만 등록해서 공유함)하기 때문에 같은 스프링 빈이면 모두 같은 인터페이스임

반응형