학습일지
[Spring] IoC, DI, Autowired
Merge Log
2025. 9. 15. 11:36
IoC, DI 가 무엇인가?
IoC, DI 는 객체지향의 SOLID 원칙 그리고 GoF 의 디자인 패턴과 같은 설계 원칙 및 디자인 패턴
- 더 자세히는 IoC 는 설계 원칙, DI 는 디자인 패턴을 의미한다
- 어떤 객체가 사용하는 의존 객체를 직접 만들어 사용하는 것이 아닌, 주입 받아 사용하는 방법을 말한다
Spring IoC 컨테이너
BeanFactory()- 애플리케이션 컴포넌트의 중앙 저장소 역할
- 빈 설정 소스로부터 빈 정의를 읽고, 빈을 구성 및 제공한다
Autowired
- 해당 기능을 사용하면 스프링이 자동으로 의존성을 주입한다
- required 옵션이
true라면 의존성이 무조건 필수이기 때문에 의존성 없이 빈을 생성할 수 없다 - 사용할 수 있는 위치는 아래 세가지
- 생성자
- 세터(Setter)
- 필드
- 같은 타입의 빈이 여러개일 경우
@Primary를 통해 같은 타입의 빈이 존재할때 먼저 선택할 빈을 설정할 수 있다@Qualifier를 통해 빈의 이름(Bean ID)으로 선택하여 주입할 수 있다- 혹은 Collection 형태로 해당 타입의 모든 빈을 주입받을 수 있다
- 동작 원리는
BeanPostProcessor를 통해 동작 → 빈 라이프사이클 인터페이스의 구현체에 의해 동작- bean Instance 를 만든 이후 초기화 라이프사이클을 동작한다 (Initialization Lifecycle)
- 초기화 라이프사이클 이전/이후에 부가적인 동작을 할 수 있는 또다른 라이프사이클 콜백이 있고 그에 해당하는 것이
BeanPostProcessor이다 Autowired는 Initialization 전에 실행된다 →postProcessBeforeInitialization시점에 실행- BeanFactory(ApplicationContext) 는 BeanPostProcess 타입의 빈을 찾고 처리한다 → 이때
AutowiredAnnotationBeanPostProcess가BeanPostProcess타입의 빈으로 등록되어 있는 것
참고
- 빈 주입시 필드 이름을 특정 빈 이름과 똑같이 지정하면 해당 빈이 선택되어 주입된다.
(권장하지 않음)
컴포넌트 스캔
- 자동으로 특정 Annotation 이 등록된 객체를 식별 후 빈으로 등록하는 기능
- 수동으로 빈을 등록하는 방법에는 자바(
@Configuration) 과 xml 등을 통한 방식이 있고ApplicationContext를 통해 빈으로 등록 및 처리하는 과정이 존재한다 - 우리가 사용하는 스프링 부트의
@SpringBootApplication은@Configuration이다 즉 부트의 시작점 코드 자체가 빈 수동처리를 위한 자바 config 코드인 것 이다 + 컴포넌트 스캔 Annotation 또한 추가되어있다 - 중요한 것은 "스캔은 어디부터 어디까지 스캔할 것 인가" / "스캔 중 어떤 것들을 제외해야하는가" 이다
- 실제 스캐닝은
ConfigurationClassPostProcessor라는BeanFactoryPostProcessor에 의해 처리된다
스프링에서 싱글톤을 보장하는 비밀
- 우리가 자바를 통해 수동으로 빈을 등록하는 방법에는
@Configuration을 사용할 수 있다 AnnotationConfigApplicationContext(AppConfig.class)를 통해getBean(AppConfig.class)를 한다면 우리가 실제로 만든 클래스가 아닌AppConfig$$EnhancerBySpringCGLIB$$~~형태의 클래스가 사용된다- 해당 바이트코드 조작을 통해 싱글톤을 보장한다 (예시: "만약 해당 빈이 있다면 반환 / 없다면 빈 생성")