DI(Dependency Injection)

의존성 주입

  • 의존성: 객체를 생성 및 사용함에 있어 의존관계가 있는 경우
    • A가 B를 사용한다, A가 B에 의존한다
  • 외부에서 객체 간의 관계(의존성)를 결정해 주는데 즉, 객체를 직접 생성하는 것이 아니라 외부에서 생성 후 주입시켜 주는 방식

DI 설정의 역사

  • XML을 통한 빈 등록
    • 토비의 스프링, 스프링3/4 시절까지 많이 사용
    • 설정이 외부로 명확히 분리된 것을 알 수 있음
    • 하지만 자동완성이나 컴파일 등으로 오타를 잡기 어렵고 타이핑 양이 많아짐
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="conveniencePayService" class="com.zerobase.convpay.service.ConveniencePayService">
        <constructor-arg name="paymentInterfaceSet">
            <set>
                <ref bean="moneyAdapter"/>
                <ref bean="cardAdapter"/>
            </set>
        </constructor-arg>
        <constructor-arg name="discountInterface" ref="discountByConvenience"/>
    </bean>

    <bean id="cardAdapter" class="com.zerobase.convpay.service.CardAdapter"/>
    <bean id="moneyAdapter" class="com.zerobase.convpay.service.MoneyAdapter"/>
    <bean id="discountByConvenience" class="com.zerobase.convpay.service.DiscountByConvenience"/>
    <bean id="discountByPayMethod" class="com.zerobase.convpay.service.DiscountByPayMethod"/>
</beans>
  • XML ComponentScan을 통한 빈 등록
    • 기본 빈 등록 방식은 클래스가 많은 경우 너무 번거로움
    • @Controller, @RestController, @Service, @Component, @Repository 등의 지정된 어노테이션이 붙은 클래스를 싹 빈으로 등록
1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.zerobase.convpay"/>
</beans>
  • JavaConfig를 통한 빈 등록
    • 스프링 4부터 XML이 아닌 javaConfig가 많이 활용되기 시작함
    • XML 설정파일이 자바 코드화 된 것
    • 자동완성, 컴파일시 정적 분석으로 오류를 잡아줌
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import com.zerobase.convpay.service.*;
import org.springframework.context.annotation.*;
import java.util.*;

@Configuration
public class ApplicationConfig {

    @Bean
    public ConveniencePayService conveniencePayService(){
        return new ConveniencePayService(
                new HashSet<>(Arrays.asList(moneyAdapter(), cardAdapter())),
                discountByConvenience()
        );
    }

    @Bean
    public CardAdapter cardAdapter() {
        return new CardAdapter();
    }

    @Bean
    public MoneyAdapter moneyAdapter() {
        return new MoneyAdapter();
    }

    @Bean
    public DiscountByConvenience discountByConvenience() {
        return new DiscountByConvenience();
    }
}

  • JavaConfig ComponentScan을 통한 빈 등록
    • XML의 설정 방법
    • JavaConfig에서의 설정 방법
    • 스프링 부트에서는 이 방식으로 기본적으로 적용되어 있다.
1
2
3
4
5
import org.springframework.context.annotation.*;

@Configuration
@ComponentScan(basePackages = "com.zerobase.convpay")
public class ApplicationConfig {}


다양한 빈 관련 설정 방법

  1. 빈의 구현체가 여러개인 경우 주입받는 방법
    1. @Primary: 해당 빈을 최우선으로 주입
    2. @Qualifier(”beanName”): beanName으로 지정된 빈을 주입
    3. Set 또는 List로 모두 받기
    4. 프로퍼티 이름을 빈과 동일하게 하기: 가장 흔하게 사용하는 방법
  2. 빈의 스코프(Scope)
    • singleton: 일반적 방법, 하나만 만들어서 계속 재활용
    • prototype: 매번 새로 만드는 방법(데이터를 클렌징 해야할 때)
      • request: 요청에 따라 새로 생성
      • session: 세션마다 새로 생성
  3. 스프링의 환경설정: 프로파일(Profile)
    • 현업에서는 환경을 다양하게 하여 해당 환경에서만 동작하는 Bean을 만드는 경우가 있음
    • 클래스단위에 적용하거나 메서드 단위에 적용 가능
      • 클래스 단위
        • @Configuration @Profile(“test”)
        • @Component @Profile(“test”)
      • 메서드 단위
        • @Bean @Profile(“test”)
      • -Dspring.profiles.active=sandbox, beta, production
      • 프로파일 표현식
        • @Profile(“!production”)
        • !not, &and, |or


IOC(Invension Of Control)

제어의 역전

  • 사용자가 직접 클래스를 생성(new Class()) 하지 않고 프레임워크가 제어하도록 함
  • 하지만 그래도 생성 전과 후에 뭔가 하고 싶은게 있으면?
    • Bean LifeCycle callback(빈 생명주기 콜백함수)
      • CallBack함수란?
        • Call(호출) Back(나중에) 하는 함수
        • 우리가 여기에 뭔가 담아주면 나중에(정의된 시점에) 호출해준다.

카테고리:

업데이트:

댓글남기기