Spring DI
:book: Contents
DI(Dependency Injection, 의존성 주입)
Spring 프레임워크에서 지원하는 IoC의 형태이다.
클래스 사이의 의존관계를 빈 설정 정보를 바탕으로 컨테이너가 자동적으로 연결해주는 것을 말한다. 개발자들은 제어를 담당할 필요없이 빈 설정 파일에 의존관계가 필요하다는 정보만 추가해주면 된다.
컨테이너가 실행 흐름의 주체가 되어 애플리케이션 코드에 의존 관계를 주입하고, 이로 인해 실행 시에 동적으로 의존 관계가 생성된다.
의존성(Dependency)
현재 객체가 다른 객체와 상호작용(참조)하고 있다면 다른 객체들을 현재 객체의 의존이라 한다.
의존성이 위험한 이유
- 모듈 간 결합도가 높아져 강한 결합이 된다.(다른 클래스를 직접적으로 사용하여 클래스 간 의존성이 높아진다.)
- 코드 유연성과 재사용성을 줄이고, 코드 변경을 어렵게 한다.
- 하나의 모듈이 바뀌면 의존한 다른 모듈까지 변경되야 한다.
- 시험 가능성을 지연시킨다.
- 다른 모듈로부터 독립적으로 테스트할 수 없기에 단위 테스트 작성이 어렵다.
- 코드 유연성과 재사용성을 줄이고, 코드 변경을 어렵게 한다.
- 모듈 간 결합도가 높아져 강한 결합이 된다.(다른 클래스를 직접적으로 사용하여 클래스 간 의존성이 높아진다.)
DI의 장점
모듈 간 결합도가 제거되어 느슨한 결합이 가능하다.(클래스 간 의존성을 줄인다.)
- 코드 유연성과 재사용성을 높이고, 코드 변경 가능성을 높인다.
- 다른 클래스와 독립적으로 클래스를 단위 테스트 할 수 있다.
SRP(Single Responsibility Principle)를 준수할 수 있다.
- 애플리케이션의 각 클래스와 컴포넌트가 명확하게 정의된 특정 책임을 갖도록 설계할 수 있다.
코드가 단순해진다.
DI의 세가지 방법
Contructor Injection : 생성자 주입
- 의존성을 입력 받는 생성자를 만들고 이를 통해 의존성을 주입한다.
Method(Setter) Injection : 메소드 매개 변수 주입
- 필요한 의존성을 포함하는 클래스의 생성자를 만들고 이를 통해 의존성을 주입한다.
- 변수에 @Autowired를 지정하면 스프링은 자동으로 setter 주입을 사용한다.
Field Injection : 멤버 변수 주입
- 의존성을 입력 받는 일반 메서드를 만들고 이를 통해 의존성을 주입한다.
생성자 주입 vs setter 주입
- 불변 객체에는 생성자 주입 사용
- setter 주입 사용 시 생성 중 오브젝트 상태가 변경되기 때문
- 클래스에 많은 의존 관계가 있다는 것을 숨길 시 setter 주입 사용
- 생성자 주입 사용 시 생성자의 크기가 증가하므로 이것이 드러남
- 불변 객체에는 생성자 주입 사용
DI(Dependency Injection. 의존성 주입) 관련 개념 정리
빈(Bean)
- 스프링 IoC 컨테이너가 관리하는 객체
- 스프링이 직접 생성과 제어를 담당
- @Bean 을 사용하거나 xml 설정을 통해 일반 객체를 Bean으로 등록할 수 있고, Bean으로 등록된 객체는 쉽게 주입하여 사용 가능
빈 팩토리(Bean Factory)
- 스프링의 IoC를 담당하는 핵심 컨테이너
- Bean을 등록, 생성, 조회, 반환하는 기능 담당
애플리케이션 컨텍스트(Application Context)
- 빈 팩토리를 확장한 IoC 컨테이너
- 스프링이 제공하는 각종 부가 서비스를 추가로 제공
- 주로 사용됨
설정 메타정보(Configuration metadata)
- 애플리케이션 컨텍스트 또는 빈 팩토리가 IoC를 적용하기 위해 사용하는 메타정보
- IoC 컨테이너에 의해 관리되는 빈 객체를 생성/구성
Bean 등록 어노테이션
- @Compoment : 스프링 빈을 정의하는 일반적인 방법. 개발자가 작성한 class를 기반으로 실행 시점에 인스턴스 객체를 1회(싱글톤) 생성
- @Bean : 개발자가 작성한 method를 기반으로 메서드에서 반환하는 객체를 인스턴스 객체로 1회(싱글톤) 생성
- @Repository : 퍼시스턴스 레이어의 데이터베이스 관련 클래스를 정의
- @Service : 서비스 레이어의 비즈니스 로직을 가진 클래스 정의
- @Controller : 프레젠테이션 레이어의 웹 어플리케이션의 요청/응답을 처리하는 클래스 정의
Bean 등록 및 의존관계 설정 어노테이션
@Configuration
- 스프링 IoC 컨테이너가 해당 클래스를 빈 정의 설정 용도로 사용하게끔 한다.
@ComponentScan
- @Component를 통해 자동으로 빈을 등록하고, @Autowired로 의존 관계를 주입 받는 어노테이션을 클래스에서 선언하여 사용했을 경우, 해당 클래스가 위치한 특정 패키지를 Scan하여 빈과 의존 관계를 식별한다.
- xml 파일에 설정하는 것도 가능하다.
@Autowired
- 스프링 컨테이너에 등록한 빈에게 의존 관계 주입이 필요할 때, DI(의존성 주입)을 도와주는 어노테이션
- 스프링 컨테이너에 빈들을 모두 등록한 후에, 의존성 주입 단계가 이루어진다. 이 때 @Autowired 어노테이션이 부여된 해당 변수 및 메서드에 스프링이 관리하는 Bean을 자동으로 매핑해주는 개념이다. 즉, 메서드가 실행되며 필요한 인스턴스를 주입하여 의존 관계를 주입하거나 해당 변수에 자동으로 빈을 매핑하여 의존 관계를 주입 받는다.
- 변수, setter 메서드, 생성자, 일반 메서드에 적용 가능
- 의존 객체 주입 시 주로 Type 이용
- @Autowired 가 Type으로 찾아서 주입하므로 동일한 Bean 타입의 객체가 여러 개 있을 경우, Bean을 찾기 위해 @Qualifier 어노테이션을 같이 사용해야 합니다.
- 스프링 컨테이너에 등록한 빈에게 의존 관계 주입이 필요할 때, DI(의존성 주입)을 도와주는 어노테이션
@Resource
- 어플리케이션에서 필요로 하는 자원을 자동 연결
- 변수, setter 메서드에 적용 가능
- 의존 객체 주입 시 주로 Name 이용
@Value
- 단순 값 주입용
@Qualifier
- @Autowired 어노테이션과 같이 사용된다.
- 동일한 타입의 빈 객체가 여러 개 존재할 때 특정 빈을 찾는 용도
@Primary
- 특정 의존 관계를 오토와이어링할 수 있는 후보가 둘 이상 있을 때, 이 어노테이션을 사용한 빈이 호출된다.
Bean 생명주기
객체 생성 -> 의존 설정 -> 초기화 -> 사용 -> 소멸
스프링 컨테이너에 의해 생명주기 관리
스프링 컨테이너 초기화 시 빈 객체 생성, 의존 객체 주입 및 초기화
스프링 컨테이너 종료 시 빈 객체 소멸
Bean 초기화 방법 3가지
- 빈 초기화 메소드에
@PostConstruct
사용
- 빈 정의 xml에
<context:annotation-config></context:annotation-config>
추가
InitializingBean
인터페이스의afterPropertiesSet()
메소드 오버라이드커스텀 init() 메소드 정의
빈 정의 xml에
init-method
속성으로 메소드 이름 지정또는 빈 초기화 메소드에
@Bean(init-method="init")
지정
Bean 소멸 방법 3가지
- 빈 소멸 메소드에
@PreDestroy
사용
- 빈 정의 xml에
<context:annotation-config></context:annotation-config>
추가
DisposableBean
인터페이스의destroy()
메소드 오버라이드커스텀 destroy() 메소드 정의
- 빈 정의 xml에
destroy-method
속성으로 메소드 이름 지정
권장하는 방법
1번 방법 (권장)
- 사용 방법이 간결하며 코드에서 초기화 메소드가 존재함을 쉽게 파악 가능하여 xml 설정 방법보다 직관적
2번 방법 (지양)
- 빈 코드에 스프링 인터페이스가 노출되어 권장하지 않으며 간결하지 않은 방법
3번 방법
- 빈 코드에 스프링 인터페이스는 노출되지 않지만, 코드만으로 초기화 메소드 호출 여부를 알 수 없는 단점
Bean Scope
singleton (default)
애플리케이션에서 Bean 등록 시 singleton scope로 등록
Spring IoC 컨테이너당 한 개의 인스턴스만 생성
컨테이너가 Bean 가져다 주입할 때 항상 같은 객체 사용
메모리나 성능 최적화에 유리
prototype
컨테이너에서 Bean 가져다 쓸 때 항상 다른 인스턴스 사용
모든 요청에서 새로운 객체 생성
gc에 의해 Bean 제거
request
Bean 등록 시 하나의 HTTP request 생명주기 안에 단 하나의 Bean만 존재
각각의 HTTP 요청은 고유 Bean 객체 보유
Spring MVC Web Application에서 사용
session
하나의 HTTP Session 생명주기 안에 단 하나의 Bean만 존재
Spring MVC Web Application에서 사용
global session
하나의 global HTTP Session 생명주기 안에 한 개의 Bean 지정
Spring MVC Web Application에서 사용
application
ServletContext 생명주기 안에 한 개의 Bean 지정
Spring MVC Web Application에서 사용
Refefence
- http://www.nextree.co.kr/p11247/
- http://wiki.javajigi.net/pages/viewpage.action?pageId=281
- http://tony-programming.tistory.com/entry/Dependency-의존성-이란
- [Spring] IOC(Inversion Of Control): 제어 역전
- [Spring] Spring Bean의 개념과 Bean Scope 종류
- Spring 빈/컨테이너 생명주기 (Lifecycle)
- SpringMVC :: 스프링 컨테이너의 생명주기, 빈의 생명주기 (Life cycle), InitialzingBean, DisposableBean, @PreDestroy, @PostConstruct
- [Spring] 빈(bean)생명주기 메소드
- [Spring] @Autowired 와 DI 개념 정리
- [Spring] @Autowired를 통한 의존 관계 주입
'Web_Backend > Spring' 카테고리의 다른 글
4.Spring MVC (0) | 2024.07.12 |
---|---|
3.Spring AOP (0) | 2024.07.12 |
1.Spring Framework와 IoC (0) | 2024.07.12 |
AOP (0) | 2022.05.03 |
Spring Filter, Interceptor, AOP 비교 (0) | 2022.05.03 |