[HometownBoard] 디테일한 빈(Bean) 등록 방법

junghan·2023년 5월 12일
0

SpringBootProject

목록 보기
19/35
post-thumbnail

Spring Bean이란?

Spring에서는 Spring의 DI Container에 의해 관리되는 POJO(Plain Old Java Objec)를 Bean이라고 부르며, 이러한 Bean들은 Spring을 구성하는 핵심 요소입니다.

Spring의 Bean을 정리하면 아래와 같습니다.

  • POJO(Plain Old Java Object)로써 Spring 애플리케이션을 구성하는 핵심 객체입니다.
  • Spring IoC 컨테이너(또는 DI 컨테이너)에 의해 생성 및 관리되고, class, id, scope, constructor-arg 등을 주요 속성으로 지닙니다.

POJO는 다음과 같은 특징을 갖습니다:

  • 특정 인터페이스나 클래스를 상속받거나 구현하지 않습니다.
  • 특정 프레임워크나 라이브러리에 종속적이지 않습니다.
  • 일반적인 getter와 setter 메서드를 포함하여 필드에 접근하는 메서드를 제공합니다.
  • 직렬화(Serialization) 및 역직렬화(Deserialization)를 지원합니다.
    POJO는 주로 데이터 전달 객체(Data Transfer Object, DTO)로 사용되며, 데이터를 담고 있는 객체로 사용자 정의 클래스를 의미합니다. POJO는 비즈니스 로직을 포함하지 않으며, 주로 데이터를 저장하고 접근하기 위한 간단한 메서드를 가지고 있습니다.

IoC컨테이너는 빈을 어떻게 관리할까?

  1. 컨테이너 초기화: IoC 컨테이너는 시작 시 초기화 단계를 수행합니다. 이 단계에서는 컨테이너가 설정 파일이나 어노테이션을 기반으로 빈 정의를 로드하고, 필요한 리소스를 설정합니다.

  2. 빈 인스턴스화: 컨테이너는 빈의 클래스를 기반으로 빈의 인스턴스를 생성합니다. 일반적으로 기본 생성자를 사용하여 인스턴스를 생성하거나, 생성자나 팩토리 메서드를 이용하여 인스턴스를 생성합니다.

  3. 의존성 해결: 컨테이너는 빈 간의 의존성을 해결하기 위해 의존성 주입(Dependency Injection)을 수행합니다. 의존성은 생성자 주입, setter 주입, 필드 주입 등의 방법으로 제공될 수 있습니다. 컨테이너는 빈이 의존하는 다른 빈을 자동으로 찾아서 주입합니다.

  1. 빈 초기화: 컨테이너는 빈의 초기화를 수행합니다. 이 단계에서는 빈의 프로퍼티 값을 설정하거나 초기화 메서드를 호출합니다. 초기화 메서드는 빈이 사용 가능한 상태가 되도록 추가적인 설정 작업을 수행합니다.
  1. 빈 사용: 초기화가 완료된 빈은 컨테이너에서 사용될 준비가 된 상태입니다. 개발자는 빈을 필요로 하는 곳에서 컨테이너로부터 빈을 조회하고 사용할 수 있습니다.
  1. 빈 소멸: 컨테이너가 종료되거나 더 이상 필요하지 않은 경우, 컨테이너는 빈의 소멸을 수행합니다. 이 단계에서는 종료 메서드를 호출하거나 빈이 사용한 리소스를 정리하는 등의 작업을 수행합니다.

Spring Bean 등록 방법

@Bean 어노테이션과 @Configuration 어노테이션

예를 들어 다음과 같은 클래스가 있고, 이를 스프링 컨테이너에 등록하고자 한다고 해보겠습니다.

public class JunghanResource {

}

이 클래스를 빈으로 등록하기 위해서 명시적으로 설정 클래스에서 @Bean 어노테이션을 사용해 수동으로 스프링 컨테이너에 빈을 등록하는 방법이 있습니다.
설정 클래스는 다음과 같이 @Configuration 어노테이션을 클래스에 붙여주면 되는데, @Bean을 사용해 수동으로 빈을 등록해줄 때, 메소드 이름으로 빈 이름이 결정됩니다.
그러므로 중복된 빈 이름이 존재하지 않도록 주의해야 합니다.

@Configuration
public class ResourceConfig {

    @Bean
    public JunghanResource junghanResource() {
        return new JunghanResource();
    }

}

@Configuration 안에서 @Bean이 빈으로 등록되는 과정은 간단하다. 스프링 컨테이너는 @Configuration이 붙어있는 클래스를 자동으로 빈으로 등록해두고, 해당 클래스를 파싱해서 @Bean이 있는 메소드를 찾아서 빈을 생성해줍니다.

하지만 어떤 임의의 클래스를 만들어서 @Bean 어노테이션을 붙인다고 되는 것이 아니고, @Bean을 사용하는 클래스에는 반드시 @Configuration 어노테이션을 활용하여 해당 클래스에서 Bean을 등록하고자 함을 명시해주어야 합니다.

스프링 빈으로 등록된 다른 클래스 안에서 @Bean으로 직접 빈을 등록해주는 것도 동작은 합니다. 하지만 @Configuration 안에서 @Bean을 사용해야 싱글톤을 보장받을 수 있으므로 @Bean 어노테이션은 반드시 @Configuration과 함께 사용해주어야 합니다.

@Bean 어노테이션을 사용하는 경우

수동으로 빈을 직접 등록해줘야만 하는 상황

  • 개발자가 직접 제어가 불가능한 라이브러리를 활용할 때
  • 애플리케이션 전범위적으로 사용되는 클래스를 등록할 때
  • 다형성을 활용하여 여러 구현체를 등록해주어야 할

@Component 어노테이션

수동으로 직접 빈을 등록하는 작업은 빈으로 등록하는 클래스가 많아질수록 상당히 많은 시간을 차지할 것이고, 생산력 저하를 야기합니다.

스프링에서는 특정 어노테이션이 있는 클래스를 찾아서 빈으로 등록해주는 컴포넌트 스캔 기능을 제공하는데 그것을 통해 @Component 어노테이션이 있는 클래스를 찾아서 자동으로 빈 등록을 해줄 수 있습니다.

1. 컴포넌트 스캔 설정 클래스 생성

우선, 컴포넌트 스캔을 위한 설정 클래스를 생성해야 합니다. 해당 설정 클래스에는 @ComponentScan 어노테이션을 사용하여 빈 스캔을 시작하는 범위를 지정합니다.

@Configuration
@ComponentScan(basePackages = "com.example.myapp")
public class AppConfig {
    // 추가적인 설정이 필요한 경우 작성
}

위의 예시에서는 com.example.myapp 패키지를 기준으로 컴포넌트 스캔을 수행하도록 설정되어 있습니다. 이 패키지와 하위 패키지에서 @Component 어노테이션이 붙은 클래스를 찾아 빈으로 등록합니다.

2. 컴포넌트 클래스 작성

빈으로 등록하고자 하는 클래스에는 @Component 어노테이션을 붙입니다. 이 어노테이션은 해당 클래스가 스프링 컨텍스트의 빈으로 등록되어야 함을 나타냅니다.


@Component
public class MyComponent {
    // 클래스 내용 작성
}

위의 예시에서는 MyComponent 클래스가 빈으로 등록되어야 함을 @Component 어노테이션을 통해 표시하고 있습니다.

3. 빈 사용

이제 빈으로 등록된 클래스를 다른 클래스에서 사용할 수 있습니다. @Autowired 어노테이션을 사용하여 의존성 주입을 받을 수 있습니다.

@Component
public class MyService {
    @Autowired
    private MyComponent myComponent;

    // 필요한 로직 작성
}

위의 예시에서는 MyService 클래스에서 MyComponent 빈을 @Autowired 어노테이션을 통해 주입받고 있습니다. 스프링은 해당 필드의 타입에 맞는 빈을 자동으로 주입하여 의존성을 해결합니다.

@Component를 갖는 어노테이션으로 @Controller, @Service, @Repository 등이 있으며 앞서 살펴봤던 @Configuration 역시 내부적으로 @Component를 가지고 있습니다.
또한, @SpringBootApplication에서는 @ComponentScan을 가지고 있습니다.

@Controller : 스프링 MVC 컨트롤러로 인식
@Repository : 스프링 데이터 접근 계층으로 인식하고, 데이터 계층의 예외를 스프링 예외로 변환해준다.
@Configuration : 앞서 보았듯이 스프링 설정 정보로 인식하고, 스프링 빈이 싱글톤을 유지하도록 추가 처리를 한다.
@Service: 사실 @Service는 특별한 처리를 하지 않는다. 대신 개발자들이 핵심 비즈니스 로직이 여기에 있겠구나 라고 비즈니스 계층을 인식하는데 도움이 된다.

https://www.geeksforgeeks.org/bean-life-cycle-in-java-spring/
https://mangkyu.tistory.com/75

profile
42seoul, blockchain, web 3.0

0개의 댓글