서버/Spring boot

#DI, IoC, Bean

paran21 2022. 1. 28. 12:04

#DI

강한 결합이란?

  • 다음과 같이 각각 새로운(new) 생성자를 만들어 구현하는 것.
  • 문제점 : 일부 변경시 모든 코드를 다 수정해주어야 함 → 느슨한 결합을 지향

느슨한 결합

  • 새로운 생성자를 만드는 것이 아니라 이미 생성된 객체를 가져다 씀!
  • Repository에 객체 repository1를 만들고 Service는 이 객체를, 그리고 Controller는 이 service객체를 가져다 사용한다.
Class Service1 {
	private final Repository1 repitory1;
	// repository1 객체 사용 
    public Service1(Repository1 repository1) {
    	this.repository1 = new Repository1();
		this.repository1 = repository1;
	} 
}​
  • 수정사항이 발생했을 때 하나만 변경해도 된다.

제어의 역전(IoC: Inversion of Controller)과 의존성 주입(DI: Dipendency Injection)

  • 자신이 필요한 객체를 생성해서 사용하는 것이 아니라 용도에 맞게 필요한 객체를 그냥 가져다 사용하는 것 → DI(의존성 주입)
  • 사용할 객체가 어떻게 만들어졌는지는 알 필요가 없다.

 

#스프링 IoC 컨테이너와 빈(Bean)

  • 빈(Bean) : 스프링이 관리하는 객체
  • 스프링 IoC 컨테이너 : '빈'을 모아둔 통
  • 스프링 3계층 Annotation은 모두 @Component : @Controller, @RestController, @Service, @Repository

빈 등록방법

1. @Component

  • @Component를 클래스 선언 위에 선언 → 스프링 서버가 뜰 때 객체를 생성하고 그 객체를 빈에 저장한다. 
    // 1. ProductService 객체 생성 
    ProductService productService = new ProductService();
    
    // 2. 스프링 IoC 컨테이너에 빈 (productService) 저장 
    // productService -> 스프링 IoC 컨테이너​
  • @Component public class ProductService { ... }​
  • 스프링 '빈'의 이름 : 클래스의 앞글자만 소문자로 변경한 것
  • 빈 클래스에는 '빈'아이콘이 생성된다.

- Component 적용조건

  • @ComponentScan에 설정해 준 packages 위치와 하위 packages들
  • @SpringBootApplication에 의해 default가 설정되어 있다.

2. @Bean

  • 직접 객체를 생성하여 빈으로 등록을 요청 → 스프링 서버가 뜰 때 스프링 IoC에 빈 저장
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. ProductService 객체 생성 
ProductService productService = new ProductService();

// 2. 스프링 IoC 컨테이너에 빈 (productService) 저장 
// productService -> 스프링 IoC 컨테이너​
  • 스프링 '빈'의 이름 : @Bean이 설정된 함수명
  • 빈 클래스에는 '빈'아이콘이 생성된다.

빈 사용방법

1. @Autowired

  • 맴버변수 선언 위에 @AutoWired → 스프링에 의해 DI됨
    @Component 
    public class ProductService {
    
    	@Autowired 
        	private ProductRepository productRepository;
    	
        	// ...
    }​
  • 빈을 사용할 메소드 위에 @AutoWired → 스프링에 의해 DI됨
    @Component 
    public class ProductService {
    
    	private final ProductRepository productRepository;
    
    	@Autowired 
        	public ProductService(ProductRepository productRepository) {
        		this.productRepository = productRepository;
    	}

- @Autowired 적용조건

  • 스프링 IoC컨테이너에 의해 관리되는 클래스에서만 가능

- @Autowired 생략조건

  • Spring 4.3버전부터 생략가능
  • 생성자 선언이 1개일 때만 생략가능
  • Lombok의 @RequiredArgsConstructor
    @RequiredArgsConstructor // final로 선언된 멤버 변수를 자동으로 생성합니다.
    @RestController // JSON으로 데이터를 주고받음을 선언합니다.
    
    public class ProductController {
    	private final ProductService productService;
    
    	// 생략 가능 
        	// @Autowired 
        	// public ProductController(ProductService productService) {
        	// this.productService = productService;
    	// }
    }​

2. 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;
    	}
    }​

 

 

'서버 > Spring boot' 카테고리의 다른 글

#ORM, JPA, Spring data JPA, SQL  (0) 2022.02.05
#Spring security  (0) 2022.01.28
#Spring MVC  (0) 2022.01.26
#H2연동하기  (0) 2022.01.26
#Model과 ModelAndView  (0) 2022.01.26