해당 내용은 김영한씨의 강의 및 스프링 프레임워크 공식 문서를 번역하여 작성한 글입니다.

특히 공식 문서에 있어 올바르지 않은 번역 의견은 언제든지 환영합니다. 댓글 달아주세요

 

1. Dependency Injection, DI

DI 설명

위의 코드에서 OrderServiceImpl는 현재 memberRepository, discountPolicy를 의존(Dependency)하고 있다. 그리고 생성자를 통해 OrderServiceImpl이 의존하고 있는 memberRepository, discountPolicy를 주입(Injection) 받았다. 이것을 의존성 주입이라고 한다. DI의 방법은 Constructor-based Dependency Injection 와 Setter-based Dependency Injection 2가지가 있다.

 

2. Constructor-based Dependency Injection, 생성자 기반 의존성 주입

생성자 기반 의존성 주입은 컨테이너가 여러 인수로 생성자를 호출하여 수행되며, 각각 종속성을 나타낸다. 

생성자를 이용하여 의존 객체를 주입할 때는 <constructor-arg> 태그를 사용한다. 의존 객체를 두 개 이상으로 사용할 때도

<constructor-arg>를 사용하여 순서대로 작성해주면 된다.  아래는 스프링 공식 문서에 작성되어 있는 예제이다. 

Consturctor-based Dependency Injection 예제

3. Setter-based Dependency Injection, 세터 기반 의존성 주입

set으로 시작하는 설정 메서드를 통해서 의존성 주입하는 방법이다. 해당 방법은 다음과 같은 형식을 지닌다.

  • 메서드 이름이 set으로 시작한다.
  • set뒤에는 프로퍼티* 이름의 첫글자를 대문다로 치환한 이름을 사용한다. (예: setCamelCase)
  • 한개의 파라미터를 가지며, 파라미터의 타입은 프로퍼티의 타입이다. 

아래는 스프링 공식 문서에 작성되어 있는 예제이다. 

Setter-based Dependency Injection 예제

4. Constructor-based or setter-based DI?

생성자 기반 DI와 설정자 기반 DI를 혼합할 수 있으므로 필수 종속성에는 생성자를 사용하고 선택적 종속성에는 설정 방법 또는 구성 방법을 사용하는 것이 좋다. 설정자 메서드에서 @Autowired 주석***을 사용하여 속성을 필수 종속성으로 만들 수 있지만, 인수의 프로그램적 유효성 검사를 사용하는 생성자 주입이 선호된다.


*** 스프링 빈이 없어도 동작하길 원한다면 @Autowired(return=false), public void setNoBean2(@Nullable Member member) , public void setNoBean3(Optional member)로 작성한다. @Nullable,Optional는 null, Optional.empty를 반환해준다. 


Spring 팀은 일반적으로 생성자 주입을 지지한다. 응용 프로그램 구성 요소를 불변 개체로 구현하고 필요한 종속성이 null이 되지 않도록 보장하기 때문이다. 또한 생성자가 주입한 구성 요소는 항상 완전 초기화 상태에서 클라이언트(호출) 코드로 반환된다. (객체 생성할 때 딱 1번 호출되고 이후에 호출되는 일이 없다) 부가적으로, 많은 수의 생성자 인수는 나쁜 코드이며, 이는 클래스가 너무 많은 책임을 가지고 있을 가능성이 있으며 적절한 문제 분리를 더 잘 해결하기 위해 리팩터링되어야 한다는 것을 의미한다.

또한 대부분의 의존관계 주입은 한번 일어나면 애플리케이션 종료시점까지 의존관계를 변경할 일이 없으며, 대부분 의존관계가 애플리케이션 종료전까지 변하면 안되므로 생성자 주입이 더 좋다.

세터 주입은 주로 클래스 내에서 합리적인 기본값을 할당할 수 있는 선택적 종속성에만 사용되어야 한다. 그렇지 않으면 코드가 종속성을 사용하는 모든 곳에서 null이 아닌 검사를 수행해야 한다. 세터 인젝션의 한 가지 이점은 세터 메소드가 해당 클래스의 객체를 나중에 재구성하거나 재인젝션할 수 있게 한다는 것이다. (: public으로 열어두어야 한다. 이것은 누군가 실수로 변경할 수도 있다.) 따라서 JMX MBeans를 통한 관리는 세터 주입을 위한 강력한 사용 사례이다.

 

 

 

 

 


* 프로퍼티 : 자바빈즈(JavaBeans)**에 규약된 프로퍼티를 의미한다. bean 클래스의 프로퍼티를 정의할 때는 public getter setter 메서드를 제공해야한다.

public class FaceBean {
    private int mMouthWidth = 90;

    public int getMouthWidth() {
        return mMouthWidth;
    }
    
    public void setMouthWidth(int mw) {
        mMouthWidth = mw;
    }
}

https://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html

 

Properties (The Java™ Tutorials > JavaBeans(TM) > Writing JavaBeans Components)

The Java Tutorials have been written for JDK 8. Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available. See Java Language Changes for a summary of updated

docs.oracle.com

** JavaBeans, 자바빈

자바빈즈 규약은 재사용 가능한 객체를 빈(Bean)으로 명명하고 있으며 다음과 같은 규약을 지니고 있다.

 

1. 자바빈은 기본 패키지가 아닌 특정한 패키지에 속해야 한다.

2. 기본 생성자가 존재해야 한다. (매개변수 값이 없는 기본 생성자)

3. 멤버변수의 접근 제어자는 private여야 한다.

4. 멤버변수에 getter/setter 메서드가 존재해야 한다.

5. 4의 getter/setter 메서드는 접근 제어자가 public이여야 한다.

https://greensky0026.tistory.com/245

 

JavaBean이란? + 자바빈 규약

JavBean 이란? 뭔가 특별한 객체나 컴포넌트일 것 같지만, 그런 것이 아닙니다. 자비빈 규약을 지켜 만들어진 클래스를 'JavaBean'이라고 합니다. 자바빈 규약 1. 자바빈은 기본 패키지가 아닌 특정한

greensky0026.tistory.com

 

참고 1) 김영한(스프링 핵심원리 - 기본편)

참고 2) 최범균(초보 웹 개발자를 위한 스프링 4 프로그래밍 입문)

참고 3) https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-factory-collaborators

 

Core Technologies

In the preceding scenario, using @Autowired works well and provides the desired modularity, but determining exactly where the autowired bean definitions are declared is still somewhat ambiguous. For example, as a developer looking at ServiceConfig, how do

docs.spring.io

'Java > Spring' 카테고리의 다른 글

[Spring] Singleton  (0) 2023.02.03
[Spring] IOC  (0) 2023.01.26
[Spring] Thymeleaf Layout Dialect 설정  (0) 2022.09.27
[Spring] 정적 웹 페이지 vs 동적 웹 페이지  (0) 2022.09.20
[Spring] 반복되는 코드 Lombok으로 줄여보기  (0) 2019.08.03

+ Recent posts