앞서 만든 User와 Team은 의존관계에 있다.
User는 자신이 어느 팀에 속하는지 알아야하기 때문이다.
이 관계를 어떻게 코드로 정의할까?
스프링은 @Autowired를 이용하여 자동 DI를 만들어낸다.
뜻 그대로 "의존성을 자동 연결"해준다는 것이다.
@Bean
class A {}
@Bean
class B {
@Autowired
private B b;
}
이 @Autowired의 원리에 대해선 구글링만해도 찾을 수 있다.
다만 간략히 말하자면, Bean으로 등록된 A 객체를 B 객체가 Bean으로 등록되기 전에 미리 값을 넣어주는 방식이다.
하지만 스프링 버전이 높아지면서, @Autowired가 점점 생략되는 추세이다.
(다음 편에서 부록으로 알아볼 것이다.)
그럼 @Autowired로 어떻게 DI를 하는지 알아보도록 하자.
우리가 흔히 쓰는 가장 직관적이며 간편한 방법이다.
class Team {
}
class User {
@Autowired
private Team team;
}
위와 같이 자신의 내부에 놓고 주입하는 방식을 말한다.
간편하지만 참조 관계를 눈으로 확인하기 어렵다.
따라서 남발하게 되면 참조 관계가 꼬일 수 있으니 주의하자.
이름 그대로 Setter 메소드를 통해 주입받는 방식이다.
class Team {
}
class User {
private Team team;
@Autowired
public setTeam(Team team) {
this.team = team;
}
}
POJO가 기본적으로 가지는 setter를 이용한 주입 방법인데,
필자는 거의 써본 기억이 없다.
왠만한건 생성자 주입으로 해결되기 때문에 그런듯 하다.
말그대로 생성자로 주입하는 방식이다.
class Team {
}
class User {
private final Team team;
public User(Team team) {
this.team = team;
}
}
아마 무의식 중에 가장 많이 쓰는 주입 방식일 것이다.
객체 생성시 필수로 생성자가 실행되기 때문에,
필드 주입과 달리 참조 관계를 눈으로 쉽게 확인할 수 있다.
사실 DI는 설계의 원리적으로 이야기할 것들이 많다.
필드 주입이냐, 생성자 주입이냐 등등
부록으로 그런 것들에 대한 필자의 생각을 적어보려 한다.
다음 편으로는 Container에 대해 알아볼 것이니,
부록이 관심없다면 넘어가면 된다 : )
아니면 부록으로!