spring boot/spring boot

spring 기본 개념 - IOC, DI

ballde 2021. 10. 18. 15:27

스프링 프레임워크란?

** 애터프라이즈급 애플리케이션: 지속적인 데이터 처리와 막대한 양의 데이터 처리와 많은 사람이 한번에 데이터에 접근하는 등의 큰 규모의 환경입니다.

 

자바 플랫폼을 위한 오픈소스 애플리케이션 프레임워크입니다. 그리고 앤터프라이즈급 애플리케이션을 개발하기 위해 모든 기능을 종합적으로 제공하는 경량화된 솔루션입니다.

 

1. Ioc(inversion of controll) → 제어의 역전 : 스프링이 의존성에 대한 주도권을 가짐

  • 제어의 역전으로 객체의 의존관계에 대한 책임을 제 3자에게 위임하는 것을 IOC 라고 함

→ 즉 직접적으로 의존성을 만들지 않고 외부에서 의존성을 가져오는 경우

  • 스프링에서는 Spring Application Context 라는 컨테이너에서 컴포넌트들을 생성 및 관리, 컴포넌트(bean)들은 내부에서 서로 연결되어 상호 작용을 이룸
  • 이 때 bean 상호 연결은 DI(의존성 주입) 패턴을 기반으로 수행
  • Ioc 컨테이너가 빈을 생성하고 관리하는 객체
    
    빈으로 등록하는 방법
    1. Component Scanning    
        - @Repository
        - @Service
    	- @Controller
    	- @Configuration
    2. 직접 일일히 xml이나 자바 설정 파일에 등록
    @Configuration
      - @Bean
    ...
    
    꺼내쓰는 방법
    @Autowired, @Inject
    ApplicationContext에서 getBean()으로 직접 꺼냄
    
    즉 new Repository() 와 같은 주입해주는 것을 IOC컨테이너가 해주는 것입니다.

2. DI (dependency injection) → 의존성 관리 : 싱글톤 관리

  • 의존성 주입은 Ioc컨테이너에 등록된 것들만 가능
  • 빈의 생성자가 단 하나이며, 생성자의 파라미터 타입이 Bean컨테이너에 등록되어 있다면, bean은 @Autowired로 의존성 주입이 가능

DI 예제

객체를 직접 생성해서 사용하지 않고, 의존을 주입 받아서 사용하는 방법
public class A {
	private B b;

	public A(B b) {
		this.b = b;
	}


	public static void main(String[] args) {
		B b= new B();
		A a = new A(B); // 의존관계 주입	
	}

}

 

@Autowired

Ioc컨테이너안에 존재하는 Bean을 자동으로 주입

@Autowired
private OwnerRepository owners

setter 의존성 주입

@Autowired
public void setOwners(OwnerReposeitory owners) {
	this.owners = owner;
}

** 생성자 — 권장됨

1. 필수로 사용되어야 하는 레퍼런스가 없이는 인스턴스를 만들지 못하게 하기 위해 -> 즉 new OwnerRepository(); 를 만들지 못하게 하기 위해

2. 단 하나만을 사용하는 것을 보장합니다. 즉 순환이 되지 않고 1번만 호출 보장

@RequiredArgsConstructor
초기화 되지 않은 final ,@NonNull이 들어간 필드가 있으면
이 필드가 파라미터로 들어간 생성자를 만들어준다.

IOC와 DI를 사용해야하는 이유는?

만약 사용하지 않는다면?? 클라이언트 코드안에서 구현 객체에 의존하고 있게됨

private final MemberRepository memberRepository = new MemoryMemberRepository();
private final DiscountPolicy discountPolicy = new FixDiscountPolicy();

정책이 바뀌어서 인터페이스를 바꿔끼우려면 클라이언트 코드를 바꿔야함 ⇒ 구현 객체에 의존 자바 코드에서 위와 같이 인터페이스로 구현한 클래스에 의존을 하게 된다. ⇒ dip 위반