본문 바로가기

백엔드/자바

스프링빈 빈 등록 (디펜던시 인젝션)

반응형

객체지향 디자인에서 프로그램 상호 간 의존성을 줄이고 유연성과 재 사용성을 높이기 위한 설계원칙으로 아래와 같이 5가지 원칙으로 구성된 SOLID 디자인 룰을 사용합니다

  • SRP (Single Responsibility): 각 클래스가 한 가지 기능만 전담하도록 설계
  • OCP (Open / Closed Principle): 기능의 확장은 가능하고 수정은 불가능하도록 설계
  • LSP (Liskov's Substitution Principle: 부모를 상속받는 클래스는 부모의 기능을 대신할 수 있도록 설계
  • ISP (Interface Segregation Principle): 고유의 기능을 전담하는 인터페이스 분리
  • DIP (Dependency Inversion Principle): 클래스와 모듈, 비즈니스 로직이 추상화에 의존하도록 설계

위 규칙 중 DIP 준수를 위한 디펜던시 인젝션에 대해 알아보겠습니다.

목차

Inversion of Control (IoC)

IoC 원칙은 필요한 객체를 일일이 생성하는 대신 객체의 생성과 관리를 스프링 컨테이너에 아웃소싱하는 방법입니다. 스프링 컨테이너는 객체의 생성과 자동으로 생성된 객체를 주입하는 Dependency Injection 기능을 제공합니다.

어노테이션 목록

어노테이션 인젝션

▶ @Component

클래스를 스프링빈으로 등록. 스프링 빈은 자바 클래스 목록으로 스프링에 의해 관리됨. 등록된 빈은 디펜던시 인젝션이 가능

@Component

▶ @Primary

인터페이스를 상속하는 클래스가 여러 개인 경우 해당 어노테이션을 사용한 클래스를 사용. 단 중복으로 사용불가

@Primary

자바코드 인젝션

▶ @Configuration

@Bean 어노테이션으로 빈 등록을 가능하게 하고 각종 구성 클래스를 사용할 수 있게 해 줌

@Configuration

▶ @Bean

스프링 컨테이너에 빈으로 등록

@Bean

공통

▶ @Autowired

디펜던시 인젝션에 사용되는 어노테이션으로 @Component 또는 @Configurationr과 @Bean 어노테이션으로 등록된 빈을 (클래스 또는 인터페이스) 찾음

@Autowired

▶ @Qualifier

인터페이스를 상속하는 클래스가 여러 개인 경우 클래스를 특정하기 위해 사용. @Primary랑 같이 사용할 경우 @Qualifier가 우선순위를 가짐

@Qualifier("<beanId>")

▶ @Lazy

스프링은 애플리케이션이 구동될 때 모든 컴포넌트를 등록하고 초기화. @Lazy 어노테이션을 사용한 컴포넌트는 요청이 있을 때 등록 및 초기화됨

@Lazy


※ application.properties에서 아래 속성을 이용하여 설정하는 것도 가능. 해당 설정의 경우 전체 컴포넌트에 영향을 주므로 컨트롤러도 요청이 있을 때까지 등록 및 초기화되지 않음

spring.main.lazy-initialization=true

▶ @SpringBootApplication

애플리케이션 콘텍스트를 생성하고 빈등록, 톰캣서버 구동. @EnableAutoConfiguration,  @ComponentScan, @Configuration 세 개의 어노테이션 기능들을 포함

@SpringBootApplication

▶ @EnableAutoConfiguration

자동설정기능 활성화

@EnableAutoConfiguration

▶ @ComponentScan

어노테이션이 사용된 패키지와 패키지가 포함하는 하위 패키지 스캔.

@ComponentScan

※ 애플리케이션 클래스에 등록된 어노테이션은 메인 패키지 안에 컴포넌트만 스캔. 따라서 아래 예시 (other 패키지)처럼 애플리케이션 패키지 밖에 패키지를 생성하는 경우 해당 패키지는 스캔 대상이 아님

해당 패키지에 메인패키지가 사용하는 코드가 포함된 경우 구동 시 아래처럼 에러 발생

이러한 경우 아래 옵션을 통해 스캔할 컴포넌트 추가 필요

@SpringBootApplication(scanBasePackages = "newPackage")
@SpringBootApplication(scanBasePackages = {"newPackage1", "newPackage2"})


디펜던시 인젝션

디펜던시 인젝션은 대표적으로 XML 파일로 설정, 자바 소스코드 사용, 자바 어노테이션 사용 등 세 가지 방법으로 가능합니다.

XML 파일로 설정

레거시 방법으로 현재는 사용되지 않음

어노테이션 인젝션

빈 생성 및 등록은 @Component 어노테이션이 함. 생성자 (필수인 디펜던시가 있을 때 사용) 또는 세터 (옵션인 디펜던시가 있을 때 사용, 디펜던시가 제공되지 않으면 앱이 자동제)를 활용한 방법을 많이 사용

어노테이션 설정

인터페이스 생성

구현 클래스 생성 후 메서드를 구현하고 @Component 어노테이션 추가

컨트롤러 생성하고 위에서 생성한 구현클래스 필드로 추가

생성자 인젝션

먼저, 어노테이션을 활용한 생성자 인젝션을 보겠습니다. 

▶ 단일

생성자를 생성하고 @Autowired 어노테이션 추가 (생성자가 하나만 존재하는 경우 어노테이션 생략가능)

▶ 복수 빈

인터페이스를 상속하는 복수의 빈이 존재하는 경우 아래처럼 오류가 발생

@Qualifier 어노테이션으로 빈 아이디 지정

세터 인젝션

세터 인젝션은 세터 또는 메서드를 사용하는 방식으로 아래와 같이 동작.

Car car = new BMW();
DemoController demoController = new DemController();
demoController.setCar(car);

메서드 또는 세터를 생성하고 @Autowired 어노테이션 추가

▶ 복수 빈

@Qualifier 어노테이션으로 빈 아이디 지정

필드 인젝션

추가로 필드에 직접 주입하는 방법도 있지만 유닛테스트에 한계가 있어 권장되지 않음

자바 소스코드 인젝션

자바코드 인젝션은 빈의 생성과 등록을 위 @Configuration과 @Bean 어노테이션을 사용합니다 (등록이 되지 않으면 아래와 같이 에러 발생). 자바코드 인젝션은 애플리케이션 본연의 코드가 아닌 제삼자의 코드도 (디펜던시들) 빈으로 등록하고 활용이 가능하게 해 줍니다.

인터페이스 생성

구현클래스 생성

빈 생성 및 등록을 위한 클래스를 생성하고 @Configuration 어노테이션을 클래스에 @Bean 어노테이션을 메서드에 각각 사용 (메서드의 이름이 빈 아이디로 등록됨)


※ 아래와 같이 빈 아이디 변경가능

@Bean("newBean")
public Car ford() {
  return new Ford();
}

호출은 어노테이션 인젝션 방식과 동일 (컨스트럭터 또는 세터 사용)

빈 라이프사이클

포스트 컨스트럭트 메서드는 컴포넌트 생성 후 프레디스트로이는 앱 가동 중지 시 작동

빈 스코프

singleton

기본값으로 단 하나의 빈 객체생성

@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)

prototype

컨테이너 요청마다 빈 하나씩 생성. 프로토타입의 경우 destroy method를 호출하지 않으므로 메모리 낭비를 방지하기 위해 직접 생성된 객체 청소필요. 기본적으로 @Lazy를 사용

@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

request

HTTP 요청에만 국한됨. 웹앱에서만 사용

session

HTTP 요청에만 국한됨. 웹앱에서만 사용

global-session

글로벌 HTTP요청에 국한. 웹앱에서만 사용.

 

이상으로 디펜던시 인젝션에 대해 알아보았습니다.


참고

SOLID Principle in Programming: Understand With Real Life Examples - GeeksforGeeks

 

SOLID Principle in Programming: Understand With Real Life Examples - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

728x90
반응형