티스토리 뷰

1. Dependecny Injection의 교과서적 정의

Allows a program design to follow the dependency inversion principle.

The clients will delegate XOR code, the injector, the responsibility of providing its dependencies.

 

예시를 들어서 말하자면, client가 car factory에 request를 보내면 car factory가 모든 차에 대한 의존성을 받는것이다.

car를 만드는 것은 factory에서 만드는것이지 client가 직접 만들 필요가 없다. 

즉, 외부의 독립체에 너의 객체의 construction과 injection을 outsource하는것이라 보면 된다.

 

Spring에서 본다면 다음과 같다.

Spring dependency Injection

My App에서 request를 받으면 Object factory, 즉 spring container에서 내가 직접 손수 Coach 객체를 직접 만드는 대신에 spring framework, spring factory가 대신 해주는 것이다.

Coach객체에는 Coach 객체의 작동을 실행하기 위한 의존적인 helper 객체들이 있을 것이다. 이것을 dependency라고 한다. 그리고 이러한 dependency를 통해 객체를 만드는 것을 Spring container가 하도록 하는것. 이것을 dependency injection이라고 한다.

 

Injection Type

Injection의 많은 방법과 타입이 spring에 있지만, 가장 일반적인 두 가지. 

1. Constructor Injection

2. Setter Injection

 

Spring Container의 주요 기능

1. Create / manage objects (Inversion of Control)

2. Inject object's dependencies (Dependency Injection)

 

Constructor Injection의 과정

1. Define dependency interface and class

2. Create a constructor in your class for injection

3. Configure the dependency injection in Spring config file.

 

Dependency Injection의 예시 - Daily fortune을 제공하는 Coach 객체생성(Constructor Injection 방법)

Step 1. Define dependency interface and class

package com.luv2code.springdemo;

public interface FortuneService {
	public String getFortune();
}
package com.luv2code.springdemo;

public class HappyFortuneService implements FortuneService {

	@Override
	public String getFortune() {
		return "Today is your lucky day!";
	}
}

Step 2. Create a constructor in your class for injection

package com.luv2code.springdemo;

public class BaseballCoach implements Coach{
	
	//define a private field for the dependency
	private FortuneService fortuneService;
	
	//define a constructor for dependency injection
	public BaseballCoach(FortuneService theFortuneService) {
		fortuneService = theFortuneService;
	}
	
	@Override
	public String getDailyFortune() {
		//use my fortuneService to get a fortune
		return fortuneService.getFortune();
	}
}

Step 3. Configure the dependency injection in Spring config file.

applicationContext.xml(Configuration file)에 dependency injection을 설정해준다.

<!-- define the dependency -->
    <bean id="myFortune"
    	class="com.luv2code.springdemo.HappyFortuneService">
    </bean>
    
    <bean id="myCoach" 
    class="com.luv2code.springdemo.BaseballCoach">
    	<!-- set up constructor injection -->
    	<constructor-arg ref="myFortune"/>
    </bean>

* Behind the scene에서 spring container가 하는 역할

myFortune bean에서의 역할은 

HappyFortuneService myFortune = new HappyFortuneServie();

myCoach bean의 역할은

BaseballCoach myCoach = new BaseballCoach(myFortune);

package com.luv2code.springdemo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HelloSpringApp {
	public static void main(String[] args) {

		// load the spring configuration file
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		
		// retrieve bean from spring container
		Coach theCoach = context.getBean("myCoach", Coach.class);
		//Coach theCoach = context.getBean(beanid, interface.class);

		//let's call our new method for fortunes
		System.out.println(theCoach.getDailyFortune());
		
		// close the context
		context.close();
	}
}

* context.getBean("myCoach", Coach.class);에서 coach interface를 명시해 주는 이유

 

interface를 메소드를 통해 넘겨주면, behind the scene에서 Spring이 객체를 만들어 준다.

하지만 일반적인 casting이랑은 약간의 차이가 있는데, Spring docs를 참고하면 다음과 같다.

 

Behaves the same as getBean(String), but provides a measure of type safety by throwing a BeanNotOfRequiredTypeException if the bean is not of the required type. This means that ClassCastException can't be thrown on casting the result correctly, as can happen with getBean(String).

 

즉 type safety, bean이 어떠한 타입인지 명시해 줌으로서 예외 발생 시 대처에 더 용이하기 때문이다.

Bean이 요구하는 type이 아닐 경우 BeanNotOfRequiredTypeException를 제시해 줄수 있고, 인터페이스를 명시해 주지 않는다면 일어날 수 있는 ClassCastException를 표현해 줄 수 없기 때문이다.

최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday