스프링 빈(Spring Bean)과 의존성 주입(DI: Dependency Injection)

2025. 3. 31. 14:52·BackEnd

스프링 빈과 의존성 주입


  • 스프링 빈이란?
    스프링 컨테이너에 의해 관리되는 객체를 스프링 빈이라고 함. 스프링 빈으로 등록된 클래스는 스프링 어플리케이션 실행 시 컨테이너가 자동으로 생성하고, 필요할때 의존성 주입까지 자동으로 하게 된다.

스프링 빈(Spring Bean)


개념

  • 스프링 컨테이너에 의해 관리되는 객체. 개발자가 직접 객체를 생성하고 관리하지 않아도 된다.
  • 기본적으로 스프링 빈의 인스턴스는 싱글톤으로 관리되기 때문에 트래픽이 많은 환경에서도 메모리 부담을 최소화할 수 있다.

싱글톤 패턴이란?

    객체의 인스턴스가 오직 1개만 생성되도록 구현한 디자인 패턴.
    생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이며, 가장 처음 호출된 생성자만 객체 인스턴스를 반환하고 이후에는 기존의 인스턴스를 반환하게 된다.

스프링빈 생성 방법


스프링 빈 생성 방법은 xml파일, @Configuration과 @Bean어노테이션 사용, @Component 어노테이션 사용으로 3가지 정도가 있다.
xml파일을 사용하는 방법은 현재는 거의 사용되지 않는 방법이기 때문에 다루지 않겠다.

  • @Configuration, @Bean 어노테이션을 사용하여 빈 등록
    • @Configuration 어노테이션으로 스프링 빈을 등록하는 클래스를 별도로 선언하고 @Bean 어노테이션으로 클래스의 생성자를 스프링 빈으로 등록함.
    • 외부 라이브러리 객체도 @Bean을 통해 빈으로 등록하여 사용할 수 있음.
    • 스프링 빈의 수가 많아질수록 모든 빈을 수동으로 등록해야되기 때문에 설정 코드가 길어진다.

@Configuration과 @Bean을 이용한 예제

  // Bean 어노테이션을 이용한 스프링 빈 생성

  @Configuration
  public class AppConfig {
          // UserService를 스프링 빈으로 등록
          @Bean
          public UserService userService() {
                  return new UserService();
          }

          // UserController를 스프링 빈으로 등록하며 UserService에 대한 의존성 주입
          @Bean
          public UserController() {
                  return new UserController(userService());
          }
          ...
  }
  • @Component 어노테이션을 사용하여 등록
    • 클래스 선언 시에 어노테이션만 추가하면 스프링 빈으로 자동으로 등록된다.
    • @Component 어노테이션을 컴포넌트 스캐너가 감지하여 빈으로 자동 등록한다.
    • @Component가 이미 내부적으로 존재하는 @Controller, @Service, @Repository를 통해서 계층에 맞는 스프링 빈을 생성한다.
    • 외부 라이브러리 클래스는 @Component 어노테이션을 붙일 수 없어서 빈으로 등록하기 어렵다.

@Component 어노테이션을 사용한 예제

  // Component 어노테이션을 이용한 스프링 빈 생성

  @RestController  // 이미 component를 포함하고 있는 어노테이션인 RestController를 사용
  @RequiredArgsConstructor
  public class UserController {
          private final UserService userService;
          ...
}

의존성 주입(Dependency Injection)


개념

  • 스프링 빈으로 등록된 객체들이 상호작용하기 위해서는 연결이 필요하다.
  • 스프링 빈을 연결하는 방법으로 다른 객체의 인스턴스를 객체 내부에서 생성하는 것이 아닌 외부에서 전달받게 한다.
  • 의존성 주입을 이요하면 객체 간 결합도를 낮추고, 유연한 코드 구조를 유지하며 유지보수성과 테스트 용이성을 높일 수 있다.

의존성 주입 방법

  • 필드 주입(Field Injection)
    • 클래스에 선언된 필드에 외부 객체의 의존성을 주입하는 방법
    • @Autowired 어노테이션 사용
    • 간결한 코드로 의존성 주입할 수 있음.
    • 테스트에 적합하지 못함. 순환 참조로 인해 무한루프가 발생할 수 있음.

필드 주입 예제

// 필드 주입(Field Injection)

@Controller
public class UserController {
        @Autowired
        private UserService userService;
        ...
}
  • 수정자 주입(Setter Based Injection)
    • 클래스의 수정 메서드인 setter를 통해 의존성을 주입함.
    • 의존성 주입을 실행하는 메서드에 @Autowired 어노테이션을 추가하는 방법
    • 코드가 실행되는 도중에 유연하게 의존성을 변경할 수 있다.
    • 필수적으로 의존성이 필요한 객체의 의존성 주입을 완벽하게 보장하지 못한다.

수정자 주입 예제

// 수정자 주입(Setter Based Injection)

@Controller
public class UserController {
        private UserService userService;

        // setter메서드를 이용하여 의존성을 주입
        @Autowired
    public void setUserService(UserService userService){
            this.userService = userService;
    }
    ...
}
  • 생성자 주입(Constructor Based Injection)
    • 생성자를 통해 외부 객체의 의존성을 주입
    • 위 2가지 방식과 다르게 인스턴스가 생성될때 단 한번 의존성 주입이 발생하는 것이 보장됨 (final) 키워드를 사용하여 불변성 보장가능.
    • 가장 많이 사용되는 방식. 순환 참조 발생 시 런타임 에러가 아닌 컴파일 에러가 발생함.

생성자 주입 예제

// 생성자 주입(Constructor Based Injection)

@Controller
public class UserController {
        private final UserService userService;

        // 생성자를 이용하여 의존성을 주입
        @Autowired
    public PetController(PetService petService){
            this.petService = petService;
    }
    ...
}


// Lombok을 이용한 생성자 주입

@Controller
@RequiredArgsConstructor  // final 변수를 위한 생성자를 대신 생성해주는 어노테이션
public class UserController {
        private final UserService userService;
        ...
}

'BackEnd' 카테고리의 다른 글

Spring에서 로깅이 필요한 이유 (SLF4J, Logback, Lombok)  (0) 2025.04.04
데이터베이스와 CRUD (JPA 개념)  (0) 2025.04.04
디자인 패턴과 패키지 구조  (0) 2025.03.29
API의 구현과 API 명세서-2  (1) 2025.03.25
API의 구현과 API 명세서-1  (2) 2025.03.21
'BackEnd' 카테고리의 다른 글
  • Spring에서 로깅이 필요한 이유 (SLF4J, Logback, Lombok)
  • 데이터베이스와 CRUD (JPA 개념)
  • 디자인 패턴과 패키지 구조
  • API의 구현과 API 명세서-2
devStudent
devStudent
저의 개발(Development) 공부(Study) 기록을 추적(Tracing) 하는 블로그입니다!
  • devStudent
    Dev_Study_Trace
    devStudent
  • 전체
    오늘
    어제
    • 분류 전체보기 (23)
      • BackEnd (11)
      • DevOps (4)
      • Algorithm (7)
      • DDD 12기 (Server) (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    boj 1992
    boj1068
    데브 옵스
    도커
    백준 1068번
    백준
    GitHub Actions
    NGINX
    백준 1092
    Divide and conquer
    devops
    알고리즘
    docker
    yml
    프록시 실습
    http 상태코드
    분할 정복 알고리즘
    boj
    리버스 프록시
    쿠버네티스
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
devStudent
스프링 빈(Spring Bean)과 의존성 주입(DI: Dependency Injection)
상단으로

티스토리툴바