Bean 등록에 관하여, DI 종류

Panda·2022년 2월 21일
0

Spring

목록 보기
7/45

이전 글에서 어노테이션으로 Bean 등록이 가능한걸 알았다.
@Componet가 포함되있는 어노테이션들
1. @Repositroy
2. @Service
3. @Controller
4. etc..

이번 시간에는 자바 코드로 직접 추가로 해서 등록하는 방법에 대해서 알아보려고 합니다.

Bean 등록 시
스프링 컨테이너에 스프링 Bean 을 등록할 때 기본적으로 싱글톤으로 등록하게 된다.
(설정으로 싱글톤이 아니게 설정 가능하긴 함.)

Bean 직접 추가

SpringConfig

@Configuration
public class SpringConfig {

    @Bean
    public MemberService memberService() {
        return new MemberService((MemoryMemberRepository) memberRepository());
    }

    @Bean
    public MemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }
}

위에 방법으로 Bean을 직접 추가해줄 수 있습니다.
@Configuration 어노테이션에 대한 설명은 이전 JPA 글에서 설명을 했기 때문에
패스하겠습니다.

Service

class MemberService(
    @Autowired
    private val memberRepository: MemoryMemberRepository
) {
    // 회원가입
    fun join(member : Member) : Long {
        validateDuplicateMember(member)
        memberRepository.save(member)
        return member.id
    }

    fun validateDuplicateMember(member: Member) {
        val result = memberRepository.findByName(member.name)
        result?.let {
            throw IllegalStateException("이미 존재하는 회원입니다.")
        }
    }

    // 전체 회원 조회
    fun findMembers() : List<Member> = memberRepository.findALl()
    fun findOne(memberId : Long) : Member? = memberRepository.findById(memberId)
}

Controller

@Controller
public class MemberController {

    // IDE는 에러난다고 표시되는데.. 제대로 작동됨. (빈 직접 추가를 인식 못하는듯?)
    private final MemberService memberService;
    
    @Autowired
    public MemberController(MemberService memberService) {
        this.memberService = memberService;
    }
}

보면 분명히 MemberService 객체에 @Component가 포함되는 어노테이션이 없는데도 불구하고
@Autowired로 주입을 받는 모습을 확인할 수 있습니다.
즉 정상적으로 SpringConfig 에서 Bean이 제대로 추가가 된것을 알 수가 있습니다.

여기서 알 수 있는 정보는
스프링 컨테이너가 관리하는 객체만 (Bean로 등록되어 있는 객체만)
@Autowired 를 통한 DI가 가능합니다.

Bean을 직접 추가 할때의 장점

여기서 만약 MemoryMemberRepository을 변경한다고 하였을 때
컴포넌트 스캔 방식은 코드를 변경해야 할 부분들이 생긴다
하지만 Bean 직접 추가 방식은 Config 부분만 변경하면 된다는 장점이 있다.

실무에서는 주로 정형화된 컨트롤러, 서비스, 리포지토리 같은 코드는 컴포넌트 스캔을 사용하고
정형화 되지않거나 상황에 따라 구현 클래스를 변경해야 하면 설정을 통해 스프링 빈으로 등록한다고 합니다.

참고 : xml Bean 등록 방식은 예전방식이라서 잘 안씀...

그리고 간단하게 DI의 종류에 대해 알아봅시다.

DI 주입

  1. 필드 주입
  2. setter 주입
  3. 생성자 주입

너무 간단한 문법이기 때문에 코드는 생략하겠습니다.

setter주입은 아무래도 public이다 보니까 추후 수정될 수 있는 여지를 남겨줘서 조금 그렇고

필드 주입 같은 경우는 간단한 로직이면 상관없는데 중간의 데이터가 바뀐다던가 하면 처리가 애매해진다고 합니다.

그래서 그런지 주로 생성자 주입을 많이 쓴다고 합니다.

p.s 중간중간 코드가 Java 와 Kotlin 혼용하여 사용할 예정입니다.
마음같아서는 Kotlin 쓰고싶긴 한데 Java로도 스프링 프로젝트 진행하는게 있어서 둘다 쓰려고 합니다.

profile
실력있는 개발자가 되보자!

0개의 댓글