본문으로 건너뛰기
안동민 개발노트 아이콘

안동민 개발노트

본문 시작
2장 : 객체지향 설계와 Spring

Spring 컨테이너 전환

순수 Java BoardConfig와 같은 회원가입 객체 그래프를 Spring 빈으로 등록하고 타입 조회·생성자 주입·모호성 실패를 확인합니다.

Spring 컨테이너는 우리가 직접 작성한 BoardConfig와 같은 객체 조립을 일관되게 수행합니다. 은 컨테이너가 만들고 관리하는 객체이고, @Bean은 메서드 반환 객체를 빈으로 등록하라는 표시입니다.


빈 정의

BoardConfig.java
@Configuration(proxyBeanMethods = false)
public class BoardConfig {
    @Bean
    MemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }

    @Bean
    PasswordHasher passwordHasher() {
        return new TestPasswordHasher();
    }

    @Bean
    MemberRegistrationService memberRegistrationService(
            MemberRepository members,
            PasswordHasher passwordHasher
    ) {
        return new DefaultMemberRegistrationService(
                members, passwordHasher);
    }

    @Bean
    LoginService loginService(
            MemberRepository members,
            PasswordHasher passwordHasher
    ) {
        return new LoginService(members, passwordHasher);
    }
}

@Bean 메서드의 매개변수는 컨테이너가 타입으로 찾습니다. 두 서비스의 MemberRepository 매개변수에는 같은 싱글톤 빈이 전달됩니다.

컨테이너 실행

try (var context = new AnnotationConfigApplicationContext(
        BoardConfig.class)) {
    var registration = context.getBean(
            MemberRegistrationService.class);
    var login = context.getBean(LoginService.class);

    Member member = registration.register(new SignUpCommand(
            "member@example.com", "회원", "secret-1234"));
    long loginId = login.authenticate(
            "member@example.com", "secret-1234");

    System.out.println(member.id() == loginId);
}

getBean은 학습과 기반 코드에서 컨테이너를 관찰하기 위한 API입니다. 일반 컨트롤러는 컨테이너를 직접 조회하지 않고 생성자로 필요한 서비스를 받습니다.

빠르게 실패하는 구성

MemberRepository 빈이 없으면 컨테이너는 MemberRegistrationService를 만들 수 없으므로 시작 중 실패합니다. 후보가 두 개인데 선택 기준이 없어도 실패합니다. 요청을 받은 뒤 null 오류가 나는 것보다 설정 단계에서 원인을 드러내는 편이 안전합니다.

No qualifying bean of type 'MemberRepository' available

수동 구성과 Spring 구성 비교

항목순수 Java 구성Spring 구성
역할·구현 설계개발자가 작성동일
객체 생성new와 필드@Bean 메서드
의존성 연결생성자 직접 호출타입 기반 매개변수 주입
공유 수명구성 객체가 관리컨테이너가 관리

Spring이 나쁜 객체 설계를 자동으로 고쳐 주지는 않습니다. 먼저 역할을 나눈 뒤 조립을 맡길 때 의미가 있습니다.