SpringBoot #1.3 - DI

텐저린티·2023년 6월 21일
0

데브코스

목록 보기
8/41
post-thumbnail

SpringBoot #1.3 - DI

Dependancy Injection(DI), Circular Dependency, 컴포넌트 스캔, Autowired, Beans Scope, Life Cycle

DI (Dependency Injection)

  • IoC 만드는 방법 중 하나
  • 객체를 주입받는 생성자 / setter 주입 패턴
  • 구현 패턴
    • 전략패턴
    • 서비스 로케이터 패턴
    • 팩토리 패턴
    • 의존관계 주입 패턴
  • Spring에서는 IoC 컨테이너인 AppConfiguration 에서 Bean 객체를 생성하고, 전달해서 DI 적용

Circular Dependency (순환참조)

  • A → B & B → A 의존관계 형성 시 발생
  • BeanCurrentlyInCreationException 발생
// 이런 경우가 순환참조 케이스
// 어플리케이션 실행 안 됨.
class objectA {
	private final objectB b;
	
	objectA (objectB b) {
		this.b = b;
	}
}

class objectB {
	private final objectA a;
	
	objectB (A a) {
		this.a = a;
	}
}

@Configuration
class CircularConfig {
	@Bean
	public objectA a(objectB b) {
		return new objectA(b);
	}
	@Bean
	public objectB b(objectA a) {
		return new objectB(a);
	}
}

public class CircularDepTester {
	psvm() {
		var annotationConfigApplicationContext = 
				new AnnotationConfigApplicationContext(
					CircularConfig.class
				);
	}
}

컴포넌트 스캔

  • @Stereotype
    • UML 다이어그램 확장 도구
    • 특정 요소를 상황이나 도메인에 알맞게 분류
    • Spring이 자동으로 등록된 Bean을 찾도록 해주는 어노테이션
  • Spring이 직접 클래스를 검색해서 Bean으로 등록해주는 기능
  • Configuration 클래스에 Bean으로 직접 등록하지 않아도 원하는 클래스를 Bean으로 등록 가능

@Stereotype

  • 컴포넌트 스캔 어노테이션 (기본형은 모든 Bean을 동일시)
  • @Component
    • @Repository
    • @Controller
    • @Service
    • @Configuration

@Autowired

생성자 기반 의존관계 주입 선택 권장 이유

→ 그러니까 생성자 주입 방식을 사용하도록 하셈 ㅇㅇ

  • 초기화 시 필요한 모든 의존 관계 형성하기 때문에 안전
  • 잘못된 패턴 찾을 수 있게 해줌
    • 많은 파라미터를 가진 생성자를 방지
  • 테스트 쉽게 함
    • 등록되지 않은 Bean에 의한 프로그램 비정상 종료 방지 가능
  • 불변성 확보
    • 멀티스레드 환경에서 Thread-Safety 를 보장 가능
  • 필드주입 @Autowired을 쓴 필드는 자동연결 후보가 됨.
    • 스프링 IoC 컨테이너에서 빈을 일치시켜 충족할 수 있는 의존성이 가장 많은 생성자가 선택
    • 후보 중 어느것도 만족할 수 없는 경우 기본생성자가 선택

Bean Scope

  • 6개의 Bean Scope (default: Singleton)
    • Singleton : 한 클래스당 Bean은 하나뿐 (Bean 객체 자체가 일치 = 동등성) → 추천
    • Prototype
    • Request
    • Sesssion
    • Application
    • Websocket

Life cycle

Bean 생성 생명주기 Callback

  1. @PostConstruct 적용된 메소드 호출
  2. Bean이 InitializingBean 인터페이스 구현 시 AfterPropertiesSet 호출
  3. @Bean 어노테이션의 initMethod 에 설정한 메소드 호출

Bean 소멸 생명주기 Callback

  1. @PreDestroy 어노테이션 적용 메소드 호출
  2. Bean 이 DisposableBean 인터페이스 구현 시 destroy호출
  3. @Bean 어노테이션의 destroyMethod 에 설정한 메소드 호출

시간순서

  1. @PostConstruct
  2. InitializingBean 추상화 메소드
  3. AppConfig 내 Bean 생성 주기
  4. AppConfig 내 Bean 소멸 주기
  5. @PreDestroy
  6. DisposableBean 추상화 메소드

참고

복수 개의 Bean 설정하기

  • 같은 인터페이스 VoucherRepository 를 상속하는 두 클래스 MemoryVoucherRepository, JdbcVoucherRepository
  • Configuration 클래스는 둘에 대한 Bean을 모두 만들었기 때문에
  • VoucherRepository 클래스로 Bean을 찾아 IoC 하려는 경우 에러 발생
  • 해결책 3가지
    • 우선권 있는 클래스에 @Primary 어노테이션 달아주기 → 추천
    • 각 클래스에 @Qualifier(”이름”) 어노테이션 달아주기
      • 다만, 다른 곳에서 같은 어노테이션으로 명시해서 DI 해줘야 함.
      • 아니면 BeanFactoryAnnotationUtils 클래스를 이용해서 qualifier 찾아줘야 함.

Configuration 클래스(파일) 관리

  • 한 프로젝트에 여러 Configuration 클래스가 있을 수 있음.
  • 이러한 경우 configuration 패키지에 파일들을 몰아넣고,
  • 전체 ApplicationConfiguration 파일에 @Component 어노테이션을 이용해서 패키지 자체를 추가하는 방식으로도 사용함.
  • 근데, @SpringBootApplication 어노테이션이 자동으로 컴포넌트 스캔을 해주므로, 그냥 이걸 쓰는게 낫다.
profile
개발하고 말테야

0개의 댓글

관련 채용 정보