스프링
1. Spring DI/IoC는 어떻게 동작하나요?
IoC (Inversion of Control) 제어의 역전
: 스프링 컨테이너가 객체의 생성, 초기화, 의존성 설정, 소멸 주기를 관리한다. 이로 인해 객체는 자신의 의존성을 알 필요 없이 필요한 시점에 주입받아 사용할 수 있음.
DI (Dependency Injection) 의존성 주입
: IoC의 구현 방식 중 하나로, 스프링 컨테이너가 객체의 의존성을 자동으로 주입해주는 방식이다.
- 생성자 주입 : 객체 생성 시 의존성을 주입
- Setter 주입 : Setter 메서드를 통해 의존성을 주입
- 필드 주입 : @Autowired 어노테이션을 통해 직접 필드에 주입
Spring DI/IoC 동작 과정
1) 스프링 컨테이너 초기화 : ApplicationContext 또는 BeanFactory를 통해 컨테이너를 초기화한다. 설정 파일 (XML, 자바 설정 파일)이나 클래스의 어노테이션에서 Bean 정보를 로드한다.
2) Bean 정의 : 빈은 컨테이너에 의해 관리되는 객체. XML, 자바 설정 파일, 어노테이션(@Component, @Service, @Repository)으로 정의된다.
3) 빈 생성 : 스프링 컨테이너가 Bean 정의를 기반으로 객체를 생성한다.
4) 의존성 주입 : 생성자, Setter, 또는 필드를 통해 의존성을 주입한다.
5) 빈 제공 : 애플리케이션이 필요할 때 @Autowired 또는 ApplicationContext.getBean()을 통해 빈을 가져온다.
6) 빈 소멸 : 컨테이너 종료 시 빈의 라이프사이클을 관리하며 필요 시 @PreDestroy 같은 메서드를 호출하여 자원을 정리한다.
주요 어노테이션
- @Component : 일반적인 빈
- @Service : 서비스 계층을 나타내는 빈
- @Repository : 데이터 계층 빈 정의
- @Controller : 웹 컨트롤러 빈
- @Autowired : 의존성 주입
- @Qualifier : 동일한 타입의 빈이 여러 개일 때 특정 빈을 지정.
- @Configuration : 자바 기반 설정 클래스 정의
- @Bean : 메서드를 호출하여 빈을 정의
장점
- 객체 간 결합도 감소 : 유연한 코드 작성 가능
- 코드 재사용성 증가 : 객체를 분리해 독립적으로 사용가능
- 테스트 용이성 : Mock 객체 주입 등을 통해 단위 테스트가 쉬움
- 관심사 분리 : 객체 생성과 비즈니스 로직을 분리
단점
- 초기 설정 복잡성 : 컨테이너 설정 및 Bean 관리는 초기 설정이 복잡할 수 있음
- 런타임 오버헤드 : 컨테이너가 객체를 관리하면서 약간의 오버헤드 발생
- 추적 어려움 : 의존성 주입이 자동화되어 코드 추적이 어려울 수 있음.
스프링의 DI와 IoC는 객체 간의 의존성을 효율적으로 관리하기 위한 개념입니다. 제어의 역전이란 객체의 생성 및 의존성 관리를 개발자가 아닌 스프링 컨테이너가 담당하는 것입니다. 의존성 주입은 의존성이 필요한 객체를 컨테이너가 자동으로 주입해주는 방식입니다. 이를 통해 객체 간 결합도를 낮추고 코드의 유연성과 재사용성을 높일 수 있습니다. (개발자가 비즈니스 로직에만 집중할 수 있도록)
XML 설정, 자바 기반 설정, 또는 @Autowired와 같은 어노테이션을 통해 IoC 컨테이너가 객체를 생성하고, 의존성을 주입합니다. 이 모든 과정은 런타임 또는 애플리케이션 시작 시 자동으로 이루어집니다.
2. Spring Bean이란?
Spring Bean
: 스프링 컨테이너에 의해 생성되고 관리되는 객체. Bean은 애플리케이션의 구성 요소로 컨테이너는 Bean의 생성부터 소멸까지 전체 생명주기를 관리한다.
특징
- 컨테이너 관리 : 스프링 컨테이너가 Bean을 생성, 의존성 주입, 초기화, 소멸을 담당한다.
- 싱글톤 기본 스코프 : 기본적으로 싱글톤으로 생성되며 애플리케이션 내에서 동일한 Bean 인스턴스를 공유한다.
- 의존성 주입 : Bean 간 의존성을 컨테이너가 주입하여 객체 간 결합도를 낮춘다.
- 생명주기 관리 : @PostConstruct, @PreDestroy와 같은 어노테이션으로 초기화 및 소멸 작업을 정의할 수 있다.
스프링 빈 정의 방법
1) XML 설정 파일
<bean id="myBean" class="com.example.MyBean"/>
2) 자바 설정 파일
@Configuration
public class AppConfig {
@Bean
public MyBean myBean() {
return new MyBean();
}
}
3) 어노테이션
: @Component, @Service, @Repository, @Controller
@Component
public class MyBean {
}
Spring Bean은 스프링 컨테이너에서 관리되는 객체를 말합니다. 스프링 컨테이너는 빈의 생성, 의존성 주입, 초기화, 소멸까지 객체의 생명주기를 관리합니다. Bean은 XML 설정, 자바 기반 설정, 어노테이션으로 정의할 수 있습니다. 스프링 빈은 IoC와 DI를 구현하는 핵심 단위로 객체 간의 결합도를 낮추고 애플리케이션의 유연성과 유지보수성을 높이는 데 기여합니다.
3. 스프링 Bean의 생성 과정
1) Bean 정의 확인
: XML 설정 파일, 자바 기반 설정 파일(@Configuration), 또는 어노테이션(@Component, @Bean)을 통해 빈이 정의된다. 이 정보를 바탕으로 BeanDefinition 객체를 생성하여 컨테이너가 빈의 설정 정보를 관리한다.
2) Bean 인스턴스 생성
: BeanDefinition을 참고하여 빈 객체를 생성합니다. 객체 생성에는 리플렉션 기술이 사용된다.
3) 의존성 주입
: 생성된 Bean에 필요한 의존성을 주입한다. > 방법 : 생성자 주입, Setter 주입, 필드 주입
4) 초기화 작업
: Bean이 완전히 생성되고 의존성이 주입된 후 초기화 작업이 수행된다.
> 방법
- @PostConstruct 어노테이션 : 초기화 작업을 위한 메서드 정의
- init-method 속성 : XML 또는 자바 설정에서 초기화 메서드 지정
- InitializingBean 인터페이스 : afterPropoertiesSet() 메서드 오버라이드
5) Bean 사용
: @Autowired, @Resource 등으로 Bean을 주입받거나, ApplicationContext.getBean() 메서드를 호출해 Bean을 가져온다
6) 소멸 작업
: 컨테이너가 종료될 때 Bean의 소멸 작업을 수행한다.
> 방법
- @PreDestroy 어노테이션 : 소멸 작업을 위한 메서드 정의
- destroy-method 속성 : XML 또는 자바 설정에서 소멸 메서드 지정
- DisposableBean 인터페이스 : destroy() 메서드 오버라이드
스프링 컨테이너가 IoC를 통해 객체의 생성, 의존성 주입, 초기화, 소멸을 관리하는 과정입니다.
1) XML, 자바 설정 파일, 어노테이션에서 Bean 정의 정보를 확인합니다.
2) 컨테이너가 Bean의 인스턴스를 생성합니다.
3) 생성자, Setter, 또는 필드 주입을 통해 의존성을 설정합니다.
4) 초기화 메서드(@PostContstruct, init-method)를 실행하여 초기화합니다.
5) 애플리케이션이 Bean을 사용합니다.
6) 컨테이너 종료 시 소멸 메서드(@PreDestroy, destroy-method)를 실행하여 소멸 작업을 진행합니다.