Spring Bean을 수동으로 등록해보자

StrayCat·2026년 2월 16일

Bean 등록 두가지 방식

Spring에서는 Bean을 등록하는 두 가지 방식이 존재합니다.

1. 자동 등록 (Component Scan)

@Component
@Controller
@Service
@Repository
public class MyService {
    // Spring이 자동으로 Bean으로 등록
}

2. 수동 등록 (@Configuration + @Bean)

@Configuration
public class MyConfig {
    @Bean
    public MyService myService() {
        return new MyService();
    }
}

언제 수동 등록을 사용할까?

수동 등록이 적합한 경우

  1. 기술 지원 Bean (Technical Support Bean)
  • 공통 로그 처리
  • 보안 설정 (PasswordEncoder, SecurityConfig 등)
  • 데이터베이스 연결 설정
  • 외부 라이브러리 객체
  1. 비즈니스 로직과 무관한 공통 관심사
  • AOP 관련 설정
  • 필터, 인터셉터
  • 메시지 컨버터

자동 등록이 적합한 경우

비즈니스 로직 Bean

  • 3 Layer Architecture - Controller, Service, Repository
  • 프로젝트 규모가 커질수록 수가 많아지므로 자동 등록이 효율적

수동 등록의 장점

  1. 명확한 설정 위치 : 설정 클래스에 모여 있어 파악이 용이함
  2. 문제 발생시 추적 용이 : 어디서 Bean이 생성되는지 명확함
  3. 외부 라이브러리 통합 : 소스 코드를 수정할 수 없는 외부 라이브러리를 Bean으로 등록할 때 필수

예제 - PasswordEncoder Bean 수동 등록

1. Configuration 클래스 작성

package com.mywork.springauth.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration  // Spring 설정 클래스임을 명시
public class PasswordConfig {
    
    @Bean  // Spring IoC 컨테이너에 Bean으로 등록
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
  • @Configuration : 이 클래스가 Spring 설정 클래스임을 표시
  • @Bean : 메서드의 반환 객체를 Sprinf IoC 컨테이너에 등록
  • Bean 이름 : 메서드명이 Bean의 이름이 됨 (passwordEncoder)

2. Bean 동작 원리

// Spring 서버 시작 시
// 1. @Bean 설정된 메서드 호출
PasswordEncoder passwordEncoder = passwordConfig.passwordEncoder();

// 2. Spring IoC 컨테이너에 Bean 저장
// Key: "passwordEncoder" (메서드명)
// Value: BCryptPasswordEncoder 인스턴스

3. 등록된 Bean 사용하기

package com.mywork.springauth;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.crypto.password.PasswordEncoder;

@SpringBootTest
public class PasswordEncoderTest {
    
    @Autowired  // Spring 컨테이너에서 passwordEncoder Bean 주입
    PasswordEncoder passwordEncoder;

    @Test
    @DisplayName("수동 등록한 passwordEncoder를 주입받아 문자열 암호화")
    void test1() {
        String password = "mypassword1234";
        
        // 암호화
        String encodePassword = passwordEncoder.encode(password);
        System.out.println("encodePassword = " + encodePassword);
        
        String inputPassword = "password5678";
        
        // 비밀번호 검증 (원본과 암호화된 비밀번호 비교)
        boolean matches = passwordEncoder.matches(inputPassword, encodePassword);
        System.out.println("matches = " + matches); // false (다른 문자열)
    }
}

프로젝트 초기 설정 체크리스트

build.gradle 설정

// Spring Security 의존성 추가
implementation 'org.springframework.boot:spring-boot-starter-security'

Security 자동 설정 비활성화 (학습 단계)

package com.mywork.springauth;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;

@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
public class SpringAuthApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringAuthApplication.class, args);
    }
}

⚠️ 실제 운영 환경에서는 Security를 제외하지 않고 사용


추가 내용

1. PasswordEncoder를 왜 Bean으로 등록할까?

싱글톤 패턴 활용

  • PasswordEncoder는 상태를 갖지 않는 무상태 (Stateless) 객체
  • 매번 새로 생성할 필요 없이 하나의 인스턴스를 재사용
  • 메모리 효율성과 성능 향상

2. BCryptPasswordEncoder의 특징

// 같은 문자열도 매번 다르게 암호화됨 (Salt 사용)
String pw1 = passwordEncoder.encode("1234");
String pw2 = passwordEncoder.encode("1234");
// pw1 != pw2 (값은 다르지만 matches()로 비교하면 true)

// 복호화 불가능 (단방향 해시)
// 원본을 알아낼 수 없고, matches()로만 검증 가능

3. 인터페이스 타입으로 주입받는 이유

@Autowired
PasswordEncoder passwordEncoder;  // 인터페이스 타입
  • DIP (의존성 역전 원칙) 준수
  • 구현체가 바뀌어도 코드 수정 최소화
  • BCryptPasswordEncoder -> SCryptPasswordEncoder 변경시 Config만 수정

정리

구분자동 등록수동 등록
사용 시점비즈니스 로직 Bean기술 지원 Bean
개수많음적음
Annotation@Component,@Service,@Repository 등@Configuration + @Bean
관리 난이도쉬움설정 파일 관리 필요
추적성분산되어 있음한 곳에 모여있어 명확
profile
알면 좋은 것보단 잊어버리기 싫은 것들을 기록합니다.

0개의 댓글