Spring Bean 자동 조립 기법

Spring 프레임워크에서 Bean을 조립하는 방법은 크게 세 가지가 있다: 애노테이션 기반 자동 구성, JavaConfig 구성, XML 구성. 이 중 JavaConfig는 XML 구성完全可以 대체할 수 있다.

구성 전략 권장 사항

애노테이션 기반 구성과 JavaConfig를 결합하여 사용하는 것이 바람직하다. 구체적인 원칙은 다음과 같다:

  • 전역 구성은 JavaConfig 사용 (데이터베이스 연결, MVC 구성 등)
  • 업무 Bean은 애노테이션 활용 (@Controller, @Service, @Repository, @Component, @Autowired, @ComponentScan)

실제 동작하는 Maven 프로젝트로 테스트해보자. Eclipse에서 Maven Java 프로젝트를 생성하고 Spring 의존성을 추가해야 한다.

핵심 원리

Spring은 두 가지 메커니즘으로 Bean 자동 조립을 수행한다:

  • 컴포넌트 스캔: 애플리케이션 컨텍스트에서 생성된 Bean을 자동 탐지
  • 자동 의존성 주입: Bean 간의 의존 관계를 자동으로 해결

1. 컴포넌트 스캔 — Spring이 인식할 수 있는 Bean 생성

@Component, @Service, @Repository, @Controller 중 하나를 사용하여 클래스를 Bean으로 등록할 수 있다. 이 애노테이션들은 해당 클래스가 컴포넌트 클래스임을 나타내며, Spring이 Bean을 생성하도록 지시한다.

import org.springframework.stereotype.Component;

@Component
public class MusicTrack {
    
    private String performer = "밴드A";
    private String title = "아침감기";
    
    public void play() {
        System.out.println("재생 중: " + title + " - " + performer);
    }
}

2. 자동 의존성 주입 — @Autowired 활용

자동 의존성 주입은 Spring이 Bean 생성 시 해당 Bean이 필요한 다른 Bean을 자동으로 연결하는 방식이다. 예를 들어, MusicPlayer Bean이 MusicTrack Bean에 의존한다면 @Autowired를 사용하여 주입할 수 있다.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MusicPlayer {
    
    @Autowired
    private MusicTrack track;
    
    public void playMusic() {
        track.play();
    }
}

3. 컴포넌트 스캔 활성화 — JavaConfig 기반

컴포넌트 스캔을 활성화하는 방법은 JavaConfig와 XML 두 가지가 있다.

@Configuration이 적용된 클래스는 구성 파일 역할을 한다. @ComponentScan은 지정된 패키지 내에서 @Component, @Service, @Repository, @Controller 애노테이션이 적용된 클래스를 모두 Bean으로 등록한다.

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan
public class PlayerConfig {
    
}

XML 기반 설정은 생략한다.

4. 자동 조립 테스트

SpringJUnit4ClassRunner를 사용하여 테스트 실행 시 자동으로 Spring 애플리케이션 컨텍스트를 생성한다. @ContextConfiguration은 구성 클래스 위치를 지정한다.

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = PlayerConfig.class)
public class MusicPlayerTest {
    
    @Autowired
    private MusicPlayer player;
    
    @Autowired
    private MusicTrack track;
    
    @Test
    public void testPlayback() {
        track.play();
        player.playMusic();
    }
}

testPlayback 메서드를 실행하면 콘솔에 두 줄이 출력된다: "재생 중: 아침감기 - 밴드A"

5. Bean ID 지정

Spring 애플리케이션 컨텍스트의 각 Bean은 고유한 ID를 가진다. 명시하지 않으면 Spring은 클래스명의 첫 글자를 소문자로 변환하여 ID로 사용한다. @Component("id") 형태로 특정 ID를 지정할 수 있지만, 자동 주입 시 변수명에는 영향을 주지 않는다.

@Component("customTrack")
public class Album {
    
    private String performer = "밴드A";
    private String title = "저녁바람";
    
    public void play() {
        System.out.println("재생: " + title + " 연주자: " + performer);
    }
}

6. 스캔 기준 패키지 설정

기본적으로 구성 클래스가 있는 패키지와 its 하위 패키지를 스캔한다. basePackages 속성을 사용하면 여러 패키지를 지정할 수 있다.

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = {"com.music.player", "com.video.player"})
public class PlayerConfig {
    
}

또는 basePackageClasses 속성을 사용하여 특정 클래스가 속한 패키지를 기준으로도 설정 가능하다.

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackageClasses = Album.class)
public class PlayerConfig {
    
}

Spring은 애플리케이션 컨텍스트를 생성할 때 해당 Bean들을 인스턴스화하고 의존 관계를 주입한다. 이 과정이 자동화되어 개발자는 명시적인 구성 코드를 줄일 수 있다.

7월 3일 00:22에 게시됨