본문 바로가기
java/Spring

Spring Bean

by 포잉띠 2024. 10. 21.

클래스들을 스프링 컨테이너에 스프링 빈으로 등록해서 애플리케이션을 실행한다는걸 알았다.

그럼 모든 클래스를 등록해야 할까? 어떻게 등록해야 할까? 같은 의문들이 생겨서 GPT를 비롯하여 구글링 한 결과를 정리하려고 한다.

 


 

첫번째 의문에 대한 결과는 당연하게도

스프링 컨테이너에 모든 빈을 등록하는것은 아니었다.

자동으로 빈을 등록하고 생성해서 애플리케이션을 관리해주는것도 아니었다.

이 부분이 쿠버네티스의 마스터노드 - 파드와 차이점이었다.

 

스프링 컨테이너에 빈을 등록하는 방법

  1. 어노테이션 기반 등록 
    - @Component, @Service, @Repository, @Controller 같은 어노테이션을 클래스에 붙이면
    스프링이 해당 클래스들을 스캔해서 알아서 빈으로 등록해준다.
  2. Java 설정 클래스
    - @Configuration 어노테이션이 붙은 설정 클래스에서 @Bean 어노테이션을 사용하여 위의 경우가 아니어도 직접 빈을 등록할 수 있다.
  3. XML 설정 파일 사용
    - log4j.properties 파일처럼 따로 XML형식의 파일에 스프링 컨테이너, 빈을 정의하고 등록하는 방법이 있는데 고전적인 방법이고 소스관리도 불편하고 XML파일 자체 가독성도 별로여서 웬만하면 쓰고싶지 않다.

 

빈으로 등록하는 클래스와 아닌 클래스

 

빈으로 등록하여 사용하는 클래스

애플리케이션의 주요 역할을 수행하는 클래스들이 빈으로 등록된다. 

대표적으로 빈을 등록할때 쓰는 어노테이션이 4가지가 있는데, 위에서 언급된 어노테이션과 같다.

구체적으로 살펴보자.

  1. Service Annotation
    - 비즈니스 로직을 처리하는 클래스에 사용
  2. Controller / RestController Annotation
    - 웹 애플리케이션에서 HTTP 요청을 처리하는 클래스에 사용
  3. Repository Annotation
    - DB와 상호작용하는 클래스
  4. Component Annotation
    - 위의 세가지 경우에 들어가지 않는 일반적인 클래스
    - 커스텀 버퍼 클래스라던가 메시지 변환기라던가... 독립적이지 않아 스프링의 관리가 필요한 클래스에 사용

 

빈으로 등록하지 않아도 되는 클래스

위에 해당되지 않는, 애플리케이션 메인로직에서 독립적으로 동작하거나 단순 데이터 처리를 위해 사용되는 클래스들

  1. 데이터 전송 객체(DTO), 엔티티(Entity)
    데이터를 저장하기 위해 사용하는 자바빈 클래스들.
    단순 요청, 응답 데이터 구조를 정의하는 getter, setter가 들어간 자바빈 클래스나 
    DB 테이블과 매핑되는 엔티티는 빈으로 등록하지 않아도 된다.
    필요한 곳에서 자유롭게 사용되어야 하기에 스프링 컨테이너 관리 아래에 들어가면 오히려 비효율적일 수 있다.
  2. 유틸리티 클래스
    정적 메소드( ex. 문자열 관련, date 관련...)를 제공하는 클래스들은 위의 클래스와 비슷하게 독립적으로 작동하고 다른 클래스들과 관계가 강하지 않거나 아예 없기때문에 빈으로 등록하지 않아도 된다.

 

빈으로 등록할지 말지 결정할 때 고려할 포인트

  1. 의존성 주입이 필요한가?
    - 의존성 주입이 필요하다 == 다른 클래스들과 구성 혹은 상속 관계에 있어 독립적이지 않을 확률이 높다.
  2. 스프링의 관리가 필요한가?
    - 스프링의 생명주기 관리 (초기화, 소멸 ....) 또는 AOP( 로그, 트랜잭션 관리 ...) 를 적용하려면 빈으로 등록해야 한다.
  3. 애플리케이션의 주요 로직을 처리하는가?
    - 비즈니스, DB, 네트워크 요청 로직 등 핵심 기능을 수행하는 클래스라면 1번의 이유와 2번의 이유로 스프링 빈으로 등록해야 한다.

 

어노테이션으로 빈을 등록한 클래스를 다시 @Configuration 클래스에 써야 할까?

안하는게 좋다.

스프링에서는 이미 컴포넌트 스캔을 통해 어노테이션(@Component, @Service, @Controller 같은..)이 붙은 클래스들을 알아서 빈으로 등록한다.

이 경우 @Configuration 어노테이션이 붙은 클래스에 다시 빈으로 등록하는 코드를 넣는다면 중복 등록으로 인한 오류가 발생할 수도 있다.

 

컴포넌트 스캔은 어떻게 쓰는걸까.

@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
    // 컴포넌트 스캔이 설정된 패키지의 클래스들은 자동으로 스캔되고 빈으로 등록돼.
}

AOP 관련 어노테이션을 사용할 때 적용되는 범위를 정해주듯이 컴포넌트 스캔도 적용되는 범위를 지정해주어야한다.

해당 범위 안에 들어있는 클래스들은 어노테이션이 붙어있다면 스프링이 알아서 스프링 컨테이너에 등록해 주기 때문에 추가로 빈을 등록하지 않아도 된다.

 

@Configuration

이름대로 설정과 관련된 어노테이션이다. 

컴포넌트 스캔으로 처리할 수 없는 특정한 빈 == 커스텀 어노테이션이나

외부 라이브러리의 빈을 등록할 때 사용한다.

외부 라이브러리라 함은 DB 관련 API나 외부 OpenAPI같은게 있겠다.

 

스프링이 제공하는 어노테이션이 진짜 응근 많아서 웬만한 기능들은 다 커버하기에 복잡한 처리를 해야하는 경우가 아니라면 사실 커스텀 어노테이션을 만들지 않는편이 좋다고 한다.

아무래도 자바 기반 프레임워크라 그런지 기본으로 제공하는게 진짜 많다.

 

어노테이션의 종류들은 다른 게시물로 정리하겠다.