런타임? 컴퓨터 프로그램이 실행되고 있는 동안의 동작

<A가 B에 의존하고 있음 >
UML에서 말하는 의존관계는 설계 모델의 관점에서 이야기하는 것
그러나 모델이나 코드에서 클래스와 인터페이스를 통해 드러나는 의존관계외에, 런타임 시에 오브젝트 사이에서 만들어지는 의존관계도 있다.
이를 런타임 의존관계, 오브젝트 의존관계라고 하는데 모델링 시점의 의존관계와는 성격이 라드다.
런타임 시에 의존관계를 맺는 대상, 즉 실제 사용 대상인 오브젝트를 의존 오브젝트(Dependency Object)라고 한다.
의존관계 주입은 구체적인 의존 오브젝트(여기서는 UserDao)와 그것을 사용할 주체, 보통 클라이언트(UserDaoTest)라고 부르는 오브젝트를 런타임 시에 연결해주는 작업을 말한다.
의존관계 주입이란 다음 세가지 조건을 충족하는 작업을 말한다.
- 클래스 모델이나 코드에는 런타임 시점의 의존관계가 드러나지 않는다. 그러기 위해서는 인터페이스에만 의존하고 있어야 한다.
- 런타임 시점의 의존관계는 컨테이너나 팩토리가튼 제 3의존재가 결정한다
- 의존관계는 사용할 오브젝트에 대한 레퍼런스를 외부에서 제공(주입)해줌으로써 만들어진다.
의존관계 주입의 핵심은 설계 시점에는 알지 못했던 두 오브젝트의 관계를 맺도록 도와주는 제3의 존재가 있다는 것이다.
DI에서 말하는 제3의 존재는 바로 관계설정 책임을 가진 코드를 분리해서 만들어진 오브젝트라고 볼 수 있다.
@Configuration
public class DaoFactory {
@Bean
public UserDao userDao() {
return new UserDao(testConnectionMaker());
}
@Bean
public ConnectionMaker testConnectionMaker() {
return new DConnectionMaker();
}
}
public class UserDao {
// 생성자의 파라미터로 이미 만들어진 오브젝트 전달
public UserDao(ConnectionMaker connectionMaker) {
this.connectionMaker = connectionMaker;
}
}
의존관계를 맺는 방법이 외부로부터 주입이 아니라 스스로 검색을 이용하기 때문에 의존관계 검색(dependecy lookup)이라고 불리는 것도 있다.
의존관계 검색은 자신이 필요로 하는 의존 오브젝트를 능동적으로 찾는다.
메소드나 생성자를 통한 주입 대신 스스로 컨테이너에게 요청하는 방법을 사용
public class UserDao {
AnnotationConfigApplicationContext ctxt =
new AnnotationConfigApplicationContext(DaoFactory.class);
this.connectionMaker = ctxt.getBean("connectionMaker", ConnectionMaker.class);
}
의존관계 검색과 의존관계 주입에서의 가장 큰 차이는 의존관계 주입에서는 주입받는 오브젝트 자신도 스프링 빈이어야 한다. 반면에 의존관계 검색에서는 검색하는 오브젝트 자신이 스프링 빈일 필요가 없다는 점이다.
DI의 장점? 다른 책임을 가진 사용 의존관계에 있는 대상이 바뀌거나 변경되더라도 자신은 영향을 받지않으며, 변경을 통한 다양한 확장방법에는 자유롭다는게 지금까지 설명한 장점
운영DB와 개발DB를 번갈아가며 써야하는 상황이라면?
@Bean
public ConnectionMaker connectionMaker() {
return new LocalDBConnectionMaker();
}
DB 연결횟수를 세는 기능 추가한다면?
public class CountingConnectionMaker implements ConnectionMaker{
int counter = 0;
private ConnectionMaker realConnectionMaker;
// 생성자
public CountingConnectionMaker(ConnectionMaker realConnectionMaker) {
this.realConnectionMaker = realConnectionMaker;
}
@Override
public Connection makeConnection() throws ClassNotFoundException, SQLException {
counter++;
return realConnectionMaker.makeConnection();
}
}
수정자 메소드? 외부에서 오브젝트 내부의 애트리뷰트 값을 변경하려는 용도로 주로 사용됨