본문 바로가기
Spring Framework/study

DI(Dependency Injection) ?

by bloodFinger 2019. 12. 23.

스프링의 핵심 개념


객체사이의 의존 관계를 자기 자신이 아닌 외부에 의해서 설정된다는 개념이다
스프링에서는 설정파일을 사용하여 손쉽게 객체간의 의존관계를 설정하기에 스프링을 DI 컨테이너라고 부르기도 한다.
DI 컨테이너는 어떤 클래스가 필요로 하는 인스턴스를 자동으로 생성, 취득하여 연결시켜주는 역활을 한다.
DI 컨테이너가 인스턴스를 생성하도록 하려면 프로그램 소스 내부에서 new 로 직접 생성하지 않고 설정파일에서 

필요로 하는 클래스의 정보를 설정해 주어야한다.

클래스간의 의존관계를 관리하기 위한 방법  2가지


- Constructor Injection (생성자)
- Setter Injection (세터)


가. Constructor Injection


: 생성자를 통해서 의존 관계를 연결시키는 것을 말한다.
: 생성자를 통해서 의존 관계를 연결하기 위해서는 XML 설정 파일에서 요소의 하위요소로 를 추가해야 한다.

1. 객체를 전달할 경우에는 ref요소를 사용

public class Foo { 
  private Bar bar; 

  public Foo(Bar bar){ 
  	this.bar = bar; 
  } 
} 

applicationContext.xml

<bean id="foo" class="Foo">
  <constructor-arg>
  	<ref bean="bar" />
  </constructor-arg>
</bean>

<bean id="bar"   class="Bar" />




2. 전달인자가 2개 이상인 경우
기본데이터 타입일 경우에는 요소를 사용하여 의존관계를 연결시키기 위한 값을 지정

public class Foo { 
	public Foo(int a, String b) { } 
} 


applicationContext.xml

<bean id="foo"   class="Foo">
  <constructor-arg   index="1"   value="Hello" />
  <constructor-arg   index="0">
  	<value>25</value>
  </constructor-arg>
</bean>

<bean id="bar"   class="Bar" />




3. type 속성을 이용하여 지정

applicationContext.xml

<bean id="foo"   class="Foo">
  <constructor-arg   type="int"   value="25" />
  <constructor-arg   type="java.lang.String"   value="Hello" /> 
</bean>



나. Setter Injection


: setter메소드를 이용하여 의존 관계를 연결시키는 것을 말한다.
: 요소의 name 속성을 이용하여 값의 의존 관계를 연결시킬 대상이 되는 필드값을 지정한다

public class Foo { 
  private Bar bar; 

  public void setBar(Bar bar){ 
  	this.bar = bar; 
  } 
} 

applicationContext.xml

<bean   id="foo"   class="Foo">
	<property   name="bar"   ref="bar"></property>
</bean>

<bean   id="bar"   class="Bar" />


자동인식을 이용한 빈 등록 : 스테레오타입 애노테이션과 빈 스캐너

모든 빈을 XML에 일일이 선언하는 것이 귀찮게 느껴질 수도 있다. 애플리케이션의 규모가 커지고 빈의 개수가 많아지면
XML 파일을 관리하기가 번거로울 수도 있다.

 

xml 문서와 같이 한곳에 명시적으로 선언하지 않고도 스프링 빈을 등록하는 방법이 있다.

빈으로 사용될 클래스에 특별한 애노테이션을 부여해주면 이런 클래스를 자동으로 찾아서 빈으로 등록 해준다

이렇게 특정 애노테이션이 붙은 클래스를 자동으로 찾아서 빈으로 등록해주는 방식을 빈 스캐닝을 통한 자동인식

빈 등록 기능이라고 하고, 이런 스캐닝 작업을 담당하는 오브젝트를 빈 스캐너 라고 한다.

import org.springframework.stereotype.Component;

@Component
public class Hello{
	...
}

@Component가 붙어 있으므로 빈 스캐너가 감지해 자동으로 빈을 등록해주는 후보가 된다.

하나의 빈이 등록되려면 최소한 아이디 클래스 이름이 메타정보로 제공되어야 한다!!

빈 스캐너가 클래스를 감지하니 클래스 이름은 간단히 가져 올 수있는데 빈의 아이디는 어디서 찾을까?

빈 스캐너는 기본적으로 클래스 이름을 빈의 아이디로 사용한다!!.

정확히 클래스 이름의 첫 글자만 소문자로 바꿔서 사용한다.

위에를 예로 들면 이름을 hello가 된다.

 

빈의 이름을 지정해주고 싶다면

@Component("annotatedHello")
public class hello{
	...
}

이렇게 이름을 넣어주면 된다.

 

-XML을 이용한 빈 스캐너 등록

<context:component-scan base-package="main.controller"/>

 

여기서 스테레오타입 애노테이션의 종류에는 아래 3종류가 있다

@Repository    DAO에서 사용

@Service          서비스 계층에서 사용

@Controller      MVC 컨트롤러에서 사용

 

특정 계층으로 분류하기 힘든 경우에는 @Component를 사용하는 것이 좋다!!

그래도 다른 스트레에오타입 애노테이션을 직접 정의해서(커스텀) 사용 할 수 있다!

 

 

 

ps)

개발 중에 생산성을 위해 빈 스캐닝 기능을 사용해서 빈을 등록하지만, 개발이 어느 정도 마무리되고 세밀한

관리와 제어가 필요한 운영 시점이 되면 다시 xml 형태의 빈 선언을 적용하는 것도 좋은 전략이라고 합니다.

즉, 스프링 애플리케이션의 개발, 테스트, 인수 테스트 , 운영과 같은 단계마다 독립된 설정정보를 두는것을 적극 권장

한다고 합니다~

 

 

'Spring Framework > study' 카테고리의 다른 글

Spring 트랜잭션 처리 @Transactional  (0) 2020.03.07
Spring Bean Scope ?  (0) 2020.03.06
IoC Container ?  (0) 2019.12.23
테스트  (0) 2019.12.20
AOP(Aspect Oriented Programming) ?  (0) 2019.12.18