[Spring] 의존성 주입
DI(Dependency Injection : 의존성 주입)
클래스 사이의 의존 관계를 자동으로 구성 (의존 관계란 ? http://natana1992.tistory.com/20)
DI 컨테이너가 인스턴스를 관리 (인스턴스 생성하고 그 과정에서 필요한 인스턴스를 설정하여 애플리케이션에 반환)
이점
인스턴스의 스코프를 제어할 수 있음(ex. 인스턴스 - 싱글톤 객체 or 매번 새로 생성)
인스턴스의 라이프 사이클을 이벤트로 제어할 수 있음
트랜잭션 관리나 로깅 처리와 같은 공통 처리를 포함할 수 있음
객체 사이의 의존 관계가 느슨해지므로 유닛 테스트를 하기 쉬워짐(인터페이스에 관해서만 의존 관계를 만들어 줌)
Bean 정의 파일
인터페이스에 어떤 실제 기능(Bean)을 제공할지를 DI 컨테이너가 관리하도록 구현한다. DI 컨테이너가 bean을 관리할 수 있도록 Bean 정의 파일(XML 정의, JavaConfig 정의)을 만든다.
JavaConfig 정의
@Configuration 애너테이션을 클래스 정의 앞에 붙여 컴파일 시 JavaConfig용 클래스임을 알려야 함
@Bean 애너테이션을 DI 컨테이너가 관리할 Bean을 생성하는 메서드 앞에 붙여야 함
-> 이 부분에서 다른 프로젝트의 config파일에 Bean 정의가 되어있는 것을 착각해서 왜 주입이 안되는지 삽질을 했다.....
Auto-wiring
DI 컨테이너에서 명시적으로 Bean을 가져오도록 하는 것이 아닌 DI컨테이너가 클래스에 Bean을 주입하도록 하는 것
@Autowired 애너테이션을 통해 DI 컨테이너가 주입해야 할 필드를 명시함
@Autowired 애너테이션을 붙인 필드를 포함한 클래스를 관리하고 관리하는 객체 중에 애너테이션이 붙은 필드에 맞는 객체를 자동으로 찾아내어 주입
ComponentScan
DI컨테이너에 등록할 Bean을 하나하나 정의하기가 번거로움
-> 스프링 프레임워크는 Component Scan 기능을 통해 Bean을 DI 컨테이너에 자동을 등록하여 이 문제를 해결
한 클래스 앞에 @ComponentScan 애너테이션을 붙이면 이 클래스의 패키지 내부의 모든 클래스를 검색하여 @Component와 같은 특정 애너테이션이 붙은 자바 클래스를 찾아내서 DI 컨테이너에 등록
이 과정을 통해 Bean 정의 파일을 만드는 과정을 생략할 수 있음
@Component 외에도 컴포넌트 스캔의 대상이 되는 애너테이션
- @Controller : MVC의 컨트롤러를 나타내는 애너테이션 (스프링4에서는 REST 웹 서비스용으로 @RestController가 있음)
- @Service : 주로 비즈니스 로직을 처리하는 역할을 담당
- @Repository : 도메인 객체를 보존하거나 얻어오고 검색하는 조작을 캡슐화하며 컬렉션 객체와 동일한 역할을 담당 (Entity에 객체에 대한 정보를 담아서 같이 사용)