'의존관계' 라는 단어부터 어렵다. 'A가 B를 의존한다.' 라는 말은 'A는 B와 아는 사이다.' 라고 이해했다. 의존도 서로 알아야 할 수 있는 거니까...ㅎㅎ
의존은 한 객체가 다른 객체를 생성하거나 메소드를 호출할 때 발생한다. 그렇다면 왜 객체 간 의존성을 줄이는게 좋을까?
-> A가 B에게 의존한다. = B가 변하면 A도 변할 수 있다.
= 변화에 유연하지 않다.
ex. 열심히 다 만들었는데 회사 정책이 바뀌었다. 정책에 맞게 수정하려고 소스를 열어보니
객체들이 이러한 의존관계를 가지고 있다면 모두 수정해야 할수도.....
*DI(Dependency Injection)* : 의존성 주입, 의존관계 주입
DI는 외부에서 객체 간 의존 관계를 결정한다. 객체를 직접 생성하지 않고 외부에서 생성 후 넣어주기 때문에 '주입'이라고 한다.
회사에서 이벤트를 구상중이다. 여러 아이디어가 나왔고 상황에 따라 하나를 선택해야 한다.
이벤트 클래스를 바로 만들어서 생성한다면?
public class EventController {
private EventA a = new EventA();
}
public class EventController {
private EventService event = new EventA();
}
만약 회사에서 결정한 이벤트가 A가 아니라 D였다. 그럼 해당 코드를 모두 수정해야한다. EventController가 아닌 곳에서도 EventA 객체를 직접 생성해서 사용했다면 그것 또한 전부...
이벤트 인터페이스(EventService)와 상황에 따른 Event 구현체 A, B, C, D... 를 만들어 두고 상황에 따라 외부에서 의존관계를 만들어 준다면?
public class EventController {
private EventService event;
public EventController(EventService event) {
this.event = event;
}
}
EventService는 생성자를 통해 EventController 객체가 생성될 때 어떤 Event 객체가 들어올지(주입될지) 알 수 없다. 즉, 이벤트 기획의 방향이 달라져도 위 소스를 수정할 필요가 없다.
스프링은 이 유연한 DI 기능을 제공한다. 스프링은 시작될 때 컨테이너에 객체를 저장해 놓는다. 이런 객체들을 bean이라고 한다.
@Controller
public class EventController {
@Autowired
private EventService event;
public EventController(EventService event) {
this.event = event;
}
}
@Configuration
public class EventConfig {
@Bean
public EventService eventService() {
return new EventA();
}
}
@Bean 어노테이션을 사용하면 컨테이너에 어떠한 객체를 저장할지 직접 지정할 수 있다. @Bean이 붙은 메소드를 모두 호출하고, 반환된 객체들을 컨테이너에 등록한다. 빈 이름은 메소드 이름으로 저장되며 특정 이름을 지정할 수도 있다.
@Bean(name="eventService123")
빈 등록은 다른 방법을 사용할 수도 있다.(ex. xml)
public class EventTest {
ApplicationContext applicationContext
= new AnnotationConfigApplicationContext(EventConfig.class);
@Test
void eventService() {
Object bean = applicationContext.getBean(EventService.class);
Assertions.assertThat(bean).isInstanceOf(EventA.class);
}
}
테스트 해보면 빈으로 등록된 EventService가 EventA와 같음을 알 수 있다.
만약 이벤트가 A에서 D기획으로 바뀌었다면?
-> 의존성을 주입해주는 파일만 바꿔주면 된다. (EventConfig)
@Autowired: 컨테이너에서 해당 빈을 찾아오는 기능을 하는 어노테이션
빈을 가져오는 어노테이션은 @Resource @Inject도 있다.
다음 편에 계속...