DI

강한친구·2022년 3월 28일
0

Spring 입문

목록 보기
7/10

Drill Instuctor 가 아니다.
이전시간에 학습했던 Dependency Injection이다.

이를 이해하기 위해선 스프링 컨테이너, bean을 이해해야 한다.

스프링 빈

출처

Spring IoC 컨테이너가 관리하는 자바 객체를 빈(Bean)이라고 부른다.

스프링은 처음 어플리케이션을 작동하면, 컨테이너에 Bean이라는것들을 올린다. 그리고 이 빈에 담겨있는 정보들을 이용하여 필요한것을 불러서 사용하는 방식이다.

Bean을 컨테이너에 등록하는 방법에는 두가지 방법이 있다.

Annotation

package com.example.hellospring.controller;

import com.example.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;
    }
}

membercontroller라는 파일이 있다. 이 파일은 컨트롤러 파일인데, 잘 보면 Controller라는 어노테이션이 붙어있는것을 알 수있다.

이 컨트롤러는 MemberService를 정의하고 있는데 이 MemberService는 Constructor를 통해 외부에서 memberservice를 받아서 수행한다. (받는 방법 역시 3가지 정도 있는데 추후 설명하겠다.)

그리고 이 Constructor 위에는 @AutoWired라는 Annotation이 붙어있다.

이처럼 Annotation을 붙여놓고, Spring이 실행될 때 알아서 스캔 후 빈 등록을 하도록 하는것이 바로 Annotation 방식이다.

@Component Annotation이 등록외어 있는 Spring에서는
@Repository, @Service, @Controller, @AutoWired등의 어노테이션을 사용한다.

Control

컨트롤의 경우, 이 방법 말고는 Bean에 올릴 방법이 없다. 따라서 무조건 @Control, @AutoWired를 사용해야만 한다.

Singleton

스프링은 기본적으로 싱글톤(하나만 등록해서 사용)을 한다. 따라서 두 서비스가 Repositroy에 접근하더라도 메모리를 절약할 수 있다.

Config Coding

package com.example.hellospring;

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

Application과 같은 level에 Springconfig 파일을 만들고 그 안에 @Bean을 붙인 코드들을 생성한다.

위의 예제에서는 서비스와 레포지토리의 Bean을 만들었다.

DI의 3가지 방법

필드 주입

package com.example.hellospring.controller;

import com.example.hellospring.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class MemberController {

   @Autowired private final MemberService memberService;

이렇게 바로 Autowird 해주는 방식이다. 절대 권장하지 않는다

setter 주입

@Controller
public class MemberController {

    private final MemberService memberService;

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

다만 이러한 문제점은 실무에서 한번 setting을 하고나면 바꿀일이 없는것들도 실수로 바꾸게 될 수도 있다는 문제점이 있다.

Constructor 주입

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

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

가장 많이 쓰이는 방법이다

왜 직접 코드입력을?

이는 나중에 아무런 코드변경없이 리포지토리를 변경할 때 자바코드 방식을 사용하면 좋기때문에 이렇게 사용한다.

실무에서는 정형화된 컨트롤러, 서비스, 리포지토리 코드는 컴포넌트 스캔(annotation)을 이용하지만, 상황에 따라 구현 클래스가 변하는 경우나 정형화되지 않은 경우라면 spring bean을 이용한다.

0개의 댓글

관련 채용 정보