47) 스프링 IoC 컨테이너
👉 저희는 앞에서 DI 를 사용했을 때의 장점을 살펴 보았습니다.
그런데 DI 를 사용하기 위해서는 객체 생성이 우선 되어야 했습니다. 과연 어디서 객체 생성을 해야 할까요? 바로 스프링 프레임워크가 필요한 객체를 생성하여 관리하는 역할을 대신해 줍니다.
빈 (Bean): 스프링이 관리하는 객체
스프링 IoC 컨테이너: '빈'을 모아둔 통
👉 그럼 스프링 IoC 컨테이너에 어떻게 빈을 등록하고 사용하는지 확인해 보겠습니다.
48) 스프링 '빈' 등록 방법
@Component
@Component
public class ProductService { ... }// 1. ProductService 객체 생성
ProductService productService = new ProductService();
// 2. 스프링 IoC 컨테이너에 빈 (productService) 저장
// productService -> 스프링 IoC 컨테이너
@Component 적용 조건
@ComponentScan 에 설정해 준 packages 위치와 하위 packages 들
@Configuration
@ComponentScan(basePackages = "com.sparta.springcore")
class BeanConfig { ... }
@SpringBootApplication 에 의해 default 설정이 되어 있음
com.sparta.springcore/SpringcoreApplication.java


테스트 코드
package com.sparta.abc;
import org.springframework.stereotype.Component;
@Component
public class TestClass {
}
@Bean
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class BeanConfiguration {
@Bean
public ProductRepository productRepository() {
String dbUrl = "jdbc:h2:mem:springcoredb";
String dbId = "sa";
String dbPassword = "";
return new ProductRepository(dbUrl, dbId, dbPassword);
}
}// 1. @Bean 설정된 함수 호출
ProductRepository productRepository = beanConfiguration.productRepository();
// 2. 스프링 IoC 컨테이너에 빈 (productRepository) 저장
// productRepository -> 스프링 IoC 컨테이너
49) 스프링 '빈' 사용 방법
@Autowired
@Component
public class ProductService {
**@Autowired**
private ProductRepository productRepository;
// ...
}@Component
public class ProductService {
private final ProductRepository productRepository;
**@Autowired**
public ProductService(ProductRepository productRepository) {
this.productRepository = productRepository;
}
// ...
}
파라미터가 다른 생성자들
public class A {
@Autowired // 생략 불가
public A(B b) { ... }
@Autowired // 생략 불가
public A(B b, C c) { ... }
}
**@RequiredArgsConstructor** // final로 선언된 멤버 변수를 자동으로 생성합니다.
@RestController // JSON으로 데이터를 주고받음을 선언합니다.
public class ProductController {
private final ProductService productService;
// 생략 가능
// @Autowired
// public ProductController(ProductService productService) {
// this.productService = productService;
// }
}ApplicationContext
@Component
public class ProductService {
private final ProductRepository productRepository;
@Autowired
public ProductService(ApplicationContext context) {
// 1.'빈' 이름으로 가져오기
ProductRepository productRepository = (ProductRepository) context.getBean("productRepository");
// 2.'빈' 클래스 형식으로 가져오기
// ProductRepository productRepository = context.getBean(ProductRepository.class);
this.productRepository = productRepository;
}
// ...
}