토비의 스프링 스터디를 진행하며 3장에서 더 알아보고 싶은 내용으로 위와 같은 주제를 정했다.
이제부터 자세히 알아보자!
스프링의 DI
는 넓게 보자면 객체의 생성과 관계설정에 대한 제어권한을 오브젝트에서 제거하고 외부로 위임했다는 IoC
개념을 포괄한다.JdbcContext
를 스프링을 이용해 UserDao
객체에서 사용하게 주입했다는 건 DI의 기본을 따르고 있다고 볼 수 있다.JdbcContext
를 UserDao
와 DI 구조로 만들어야 하는 이유JdbcContext
는 그 자체로 변경되는 상태정보가 없다. 따라서 싱글톤으로 구현하는 것이 알맞다! (dataSource
가 있지만 읽기전용이기 때문에 상관없음)JdbcContext
가 DI를 통해 다른 빈에 의존하고 있기 때문이다.JdbcContext
는 DataSource
를 DI받고 있다.UserDao
와 JdbcContext
가 매우 강한 결합도를 갖는다는 것이다. 항상 두 클래스는 같이 사용되어야 한다.JdbcContext
는 테스트에서도 다른 구현으로 대체해서 사용할 이유도 없고 그럴 일도 없다. 이런 경우에는 굳이 인터페이스를 만들 필요없이 강력한 결합관계를 갖도록 코딩해도 된다. 단, 이는 최후에 선택되어야 하는 선택지이다. (절대로 귀찮아서 안만드는 것은 안된다)UserDao
내부에서 직접 DIJdbcContext
오브젝트를 갖고 있게 하는 것이다. 대형 프로젝트여도 수백개면 충분하기 때문에 별 문제가 없다.UserDao
가 직접 자기가 사용할 JdbcContext
를 만들고 초기화하는 전통적인 방법 사용UserDao
를 DI 컨테이너처럼 동작하게 만드는 것!DataSource
도 UserDao
가 대신 받아 주입해준다UserDao
와 DataSource
만 빈이다. public class UserDao {
...
private JdbcContext jdbcContext;
public void setDataSource(DataSource dataSource) {
this.jdbcContext = new JdbcContext();
this.jdbcContext.setDataSource(dataSource);
this.dataSource = dataSource;
}
JdbcContext
와 같이 인터페이스를 사용하지 않고 DAO와 밀접한 관계를 갖는 클래스를 DI에 적용하는 방법 두 가지JdbcContext
가 UserDao
의 내부에서 만들어지고 사용되면서 그 관계를 외부에는 드러내지 않는다는 장점JdbcContext
를 여러 오브젝트가 사용하더라도 싱글톤으로 만들 수 없고, DI 작업을 위한 부가적인 코드가 필요하다는 단점일반적으로 권장되는 방법은 없다.
하지만 본인이 선택한 방법에 대해 왜 그렇게 선택했는지에 대한 분명한 이유와 근거를 댈 수 있어야한다.
자신없으면 그냥 인터페이스를 만들어서 평범하게 DI를 구현하라