[Spring] DI, IoC
Spring Framework전략 (DI, IOC, AOP, PSA)
POJO; Plain Old Java Object란 '오래된 오래된 방식의 간단한 자바 오브젝트' 로써
기존의 무거운 객체를 만들게 된 것 (+ 복잡함)을 상대하여 경량급 애플리케이션 프레임워크인 Spring이 탄생하게 된다.
Spring 특징
경량
전체 스프링 크기는 1MB 남짓한 하나의 JAR 파일이다.
제어역행(IoC)
애플리케이션의 느슨한 결합을 도모한다.
관점지향
컨테이너
애플리케이션 객체의 생명주기와 설정을 포함하여 관리한다.
DI; Dependect Injection
유연하게 확장 가능한 객체를 만들어 준다.
즉, 인터페이스화 되어 있다.
이는 의존 관계 주입 기능으로, 객체를 직접 생성하는 것이 아닌 외부에서 생성하여 주입시켜주는 방식이다.
의존성 주입은 모듈 간의 결합도를 낮추고 유연성을 높인다.
두 가지 방식 중 첫 번째 방식은 객체에 new 생성자를 통해 A객체와 B객체를 직접 생성하는 방법이다.
두 번째 방식은 외부에서 생성된 객체를 setter를 통해 사용하는 방식이다.
객체에서 직접 생성하는 것이 아닌 외부인 IoC 컨테이너에서 생성된 A객체와 B객체를 조립 및 주입하여 setter나 생성자를 통해 사용한다.
스프링에서 객체를 Bean으로 부른다.
특징
- 각 클래스 간의 의존관계를 Bean Definition을 바탕으로 컨테이너가 자동으로 연결해준다.
- Bean 설정 파일에서 의존관계가 필요하다는 정보만 추가하면 된다.
- 객체 레퍼런스를 컨테이너로부터 주입받아 실행 시 동적으로 의존관계가 형성된다.
- 컨테이너가 흐름의 주체가 되어 의존관계를 주입한다.
➡️ 코드가 단순해지고 컴포넌트 간의 결합도가 느슨해지는 장점이 있다.
유형
Setter Injection
의존성을 입력받는 setter 메소드를 만들고 의존성을 주입시킨다.
Constructor Injection
필요한 의존성을 포함하는 클래스의 생성자를 만들고 이를 통해 의존성을 주입한다.
Method Injection
의존성을 입력 받는 일반 메소드를 만들고 의존성을 주입시킨다.
DI를 이용한 클래스 호출 방식
Setter Injection
<bean id="hello" class="bean.Hello">
<property name="name" value="Spring" />
<property name="printer" ref="printer" />
</bean>
<bean id="printer" class="bean.StringPrinter" />
<bean id="consolePrinter" class="bean.ConsolePrinter" />
Constructor Injection
// Hello.java
public class Hello {
...
public Hello(String name, Printer printer) {
this.name = name;
this.printer = printer;
}
}
IoC; Inversion of Control
IoC는 제어의 역전의 의미로, 객체의 생성과 생명주기 관리까지 모든 객체에 대한 제어권을 바꾼다.
메소드 및 객체의 호출 작업은 개발자가 결정하는 것이 아닌 외부에서 결정되는 것을 의미한다.
즉, 제어의 흐름을 바꾸는 것이다.
IoC 컨테이너
- 객체의 생성을 책임지고 의존성을 관리한다.
- POJO의 생성, 초기화, 서비스, 소멸에 대한 권한을 가진다.
- 개발자가 POJO를 생성하는 것이 아닌 컨테이너에게 맡긴다.
Spring 컨테이너
Spring 컨테이너가 관리하는 객체를 Bean이라 하며,
Bean을 관리하는 의미로 컨테이너를 BeanFactory라고 부른다.
BeanFactory에 여러 컨테이너 기능을 확장하여 Application Context라고 부른다.
- BeanFactory는 최상위에 있다.
- BeanFactory는 라이브러리를 관리한다.
- BeanFactory를 미리 상속 받아놓은 Application Context를 사용한다.
- ApplicationContext는 .xml 파일을 읽는다.
BeanFactory
- Spring의 IoC를 담당하는 핵심 컨테이너
- Bean 등록, 생성, 조회, 반환 관리
- BeanFactory를 바로 사용하지 않고, 이를 확장한 ApplicationContext를 사용
- getBean() 메서드 정의됨
ApplicationContext
- BeanFactory를 확장한 IoC 컨테이너
- Bean 등록, 생성, 조회, 반환 관리
- Spring의 부가 서비스 추가로 제공
- BeanFactory보다 ApplicationContext를 더 많이 사용
Configration metadata
- ApplicationContext or BeanFactory가 IoC를 적용하기 위해 사용하는 메타정보
- IoC컨테이너에 의해 관리되는 Bean 객체를 생성하고 구성할 때 사용
Bean 등록 Annotation
@Component
- 컴포넌트
- <bean> 태그와 동일한 역할
@Repository
- Persistence 레이어
- 파일, 데이터베이스 (영속성)을 가진 클래스 → 외부 I/O 작업을 처리
@Service
- Service 레이어
@Controller
- Presentation 레이어
- 웹 응답과 요청 처리
@Autowired
- 의존하는 객체를 자동으로 주입
- property, setter, 생성자, 일반 메서드에 적용 가능
- Type 이용
- <property>, <constryctor-arf> 와 동일한 역할
@Resource
- 의존하는 객체를 자동으로 주입
- 자원 자동 연결
- property, setter에 적용 가능
- Name 이용
@Value
- 값 주입 시 사용
- <property ... value="Spring" /> 과 동일한 역할
@Qualifier
- @Autowired와 같이 사용
- Bean 객체가 여러 개 존재할 때 특정 Bean을 찾기 위해 @Qualifier를 같이 사용해야한다.