2022년 4월 12일(화)
[스파르타코딩클럽] Spring 심화반 - 1주차
public class ProductService {
// 멤버 변수 선언
private final ProductRepository productRepository;
// 생성자: ProductService() 가 생성될 때 호출됨
public ProductService() {
// 멤버 변수 생성
this.productRepository = new ProductRepository();
}
public Product createProduct(ProductRequestDto requestDto) throws SQLException {
// 요청받은 DTO 로 DB에 저장할 객체 만들기
Product product = new Product(requestDto);
// 멤버 변수 사용
this.productRepository.createProduct(product);
return product;
}
강한 결합의 문제점
해결 방법
해결 방법 구체화 (느슨한 결합)
public class Repository1 {
private final String dbUrl;
private final String dbId;
private final String dbPassword;
public Repository1(String dbUrl, String dbId, String dbPassword) {
this.dbUrl = dbUrl;
this.dbId = dbId;
this.dbPassword = dbPassword;
}
...
}
Class Service1 {
private final Repository1 repitory1;
// repository1 객체 사용
public Service1(Repository1 repository1) {
// this.repository1 = new Repository1(); // 기존 코드
this.repository1 = repository1;
}
}
// 객체 생성
Service1 service1 = new Service1(repository1);
Class Controller1 {
private final Service1 service1;
// service1 객체 사용
public Controller1(Service1 service1) {
// this.service1 = new Service1(); // 기존 코드
this.service1 = service1;
}
}
DI (의존성 주입)의 이해
"제어의 역전 (IoC: Inversion of Control)"
프로그램의 제어 흐름이 뒤바뀜
현 상황 문제점: repository 선언시, 변수가 지정이 안됨.
-> DI 를 사용하기 위해서는 객체 생성이 우선
-> 스프링 프레임워크가 필요한 객체를 생성하여 관리하는 역할을 대신해 준다.
빈 (Bean): 스프링이 관리하는 객체
스프링 IoC 컨테이너: '빈'을 모아둔 통
Spring "Bean" 등록방법
@Component
@Component
public class ProductService { ... }
@Configuration, @Bean : 직접 객체를 생성하여 빈으로 등록 요청
// BeanConfiguration.js
@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);
}
}
@Autowired
멤버변수 선언 위에 @Autowired → 스프링에 의해 DI (의존성 주입) 됨
@Component
public class ProductService {
@Autowired
private ProductRepository productRepository;
// ...
}
@Autowired 적용 조건: 스프링 IoC 컨테이너에 의해 관리되는 클래스에서만 가능
@Autowired 생략 조건
Lombok 의 @RequiredArgsConstructor 를 사용하면 생략가능
@RequiredArgsConstructor // final로 선언된 멤버 변수를 자동으로 생성합니다.
@RestController // JSON으로 데이터를 주고받음을 선언합니다.
public class ProductController {
private final ProductService productService;
// 생략 가능
// @Autowired
// public ProductController(ProductService productService) {
// this.productService = productService;
// }
}
ApplicationContext: 스프링 IoC 컨테이너에서 빈을 수동으로 가져오는 방법
@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;
}
// ...
}
스프링 3계층 Annotation 은 모두 @Component
Repository 간단 설명