일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- Spring
- C++
- 커스텀 데이터 학습
- 졸프
- 2021 제9회 문화공공데이터 활용경진대회
- OG tag
- Spring Boot
- skt fellowship 3기
- @Transactional
- react native
- javascript
- google cloud
- JPA
- Loss Function
- google 로그인
- 코드업
- pandas
- matplotlib
- idToken
- Expo
- html
- AWS
- marksense.ai
- STT
- YOLOv5
- 양방향 매핑
- 순환참조
- yolo
- google login
- oauth
- Today
- Total
민팽로그
DI(Dependency Injection)와 스프링 IoC 컨테이너 본문
DI
-> 5개의 Controller가 각각 Service1을 사용하고 Service1이 Repository1을 사용한다고 가정하면 각 Controller는 Service1을 생성하고 각각의 Service1이 다시 Repository1을 생성한다.
이 때 Repository1을 생성하기 위해 id와 password를 알아야 한다면, 아래와 같이 모든 Controller는 Repository를 생성하기 위해 id와 password를 알아야 하는 상황이 된다.
1. Repository
public class ProductRepository {
private String dbId;
private String dbPassword;
// 생성자
public ProductRepository(String dbId, String dbPassword) {
this.dbId = dbId;
this.dbPassword = dbPassword;
}
}
2. Service
public class ProductService {
// 멤버 변수 선언
private final ProductRepository productRepository;
// 생성자: ProductService() 가 생성될 때 호출됨
public ProductService(String dbId,String dbPassword) {
// 멤버 변수 생성
this.productRepository = new ProductRepository(dbId, dbPassword);
}
}
3. Controller
public class ProductController {
// 멤버 변수 선언
private final ProductService productService;
// 생성자: ProductController() 가 생성될 때 호출됨
public ProductController() {
// 멤버 변수 생성
String dbId = "sa";
String dbPassword = "";
productService = new ProductService(dbId, dbPassword);
}
}
또 만약 id와 password가 바뀌게 된다면 Controller마다 모두 id와 password를 변경해 주어야 한다.
이렇게 하나의 클래스 생성자의 변화가 다른 클래스들에 영향을 주는 것을 강한 결합이라고 한다.
이러한 중복 코드와 강한 결합의 문제점은 DI를 사용하면 해결할 수 있다.
위 클래스들을 예로 들어, 어딘가에 ProductRepository가 미리 생성되어 있다면 ProductService 클래스는 미리 생성되어 있는 ProductRepository 객체를 가져다가 사용하기만 하면 된다.
String dbId = "sa";
String dbPassword = "";
ProductRepository productRepository = new ProductRepository(dbId, dbPassword);
public class ProductService {
private final ProductRepository productRepository;
public ProductService(ProductRepository productRepository) {
this.productRepository = productRepository;
}
}
ProductService productService = new ProductService(productRepository);
마찬가지로 ProductController도 미리 생성된 ProductService를 가져다 사용할 수 있다.
public class ProductController {
private final ProductService productService;
public ProductController(ProductService productService) {
this.productService = productService;
}
}
ProductController productController = new ProductController(productService);
이 상태에서 ProductRepository에 DB의 URL이 추가로 필요해져서 아래와 같이 변경되었다고 가정하자.
public class ProductRepository {
private String dbId;
private String dbPassword;
// 추가!!
private String dbUrl;
public ProductRepository(String dbId, String dbPassword, String dbUrl) {
this.dbId = dbId;
this.dbPassword = dbPassword;
this.dbUrl = dbUrl;
}
}
이제 처음과는 달리 ProductService, ProductController 클래스를 변경하지 않고도 ProductRepository가 생성되는 곳에서만 변경해주면 된다.
String dbId = "sa";
String dbPassword = "";
// 추가
String dbUrl = "jdbc:h2:mem:springcoredb";
// 변경
ProductRepository productRepository = new ProductRepository(dbId, dbPassword, dbUrl);
이렇게 하나의 객체가 다른 객체를 필요로 할 때, 객체를 직접 생성하지 않고 미리 생성되어 있는 객체를 가져오는 작업을 DI(Dependency Injection, 의존성 주입)이라고 한다.
제어의 흐름이 뒤바뀐다고 해서 IOC(Inversion of Control, 제어의 역전)이라고도 한다. 사용자가 필요한 객체를 생성해서 사용하는 것이 일반적인데, 이와 반대로 필요한 객체를 요청하면 어디에서 어떻게 만들어 졌는지 알 필요 없이 사용할 수 있게 되는 것이다.
스프링 IoC 컨테이너
DI를 사용하기 위해서는 먼저 객체가 하나 생성되어야 했다. spring framework가 이 때 필요한 객체를 생성하여 관리하는 역할을 해줄 수 있다.
- Bean: 스프링이 생성해주는 객체
- IoC container: 빈을 모아 놓은 container
즉 bean이 spring IoC container에 담겨 관리되고 이 곳에 담겨 관리되는 bean을 요청 시 DI하여 사용한다.
@Bean 어노테이션을 사용하여 IoC 컨테이너에 빈을 등록하고 @Autowired 어노테이션을 통해 빈으로 등록된 객체를 주입할 수 있다.
어노테이션들은 빈으로 등록되고 관리된다. 즉, @RestController, @Service, @Repository 모두 스프링의 빈으로 등록된다. 특히 @Repository 어노테이션은 스프링에 의해 자동으로 @Repository가 추가되니 굳이 입력하지 않아도 된다.
'🍃spring boot' 카테고리의 다른 글
스프링 AOP 개념 간단 이해 (0) | 2021.09.14 |
---|---|
[OAuth] 웹에서 카카오 소셜 로그인 (0) | 2021.09.13 |
servlet과 객체지향 프로그래밍(OOP:Object-Oriented Programming) (0) | 2021.09.12 |
[spring] scheduler - cron (0) | 2021.08.24 |
스프링 구조 - Controller, Service, Repository (0) | 2021.07.31 |