본문 바로가기

Spring

[Spring] Bean 등록 방법

 


 

 

✅ Bean 등록 방법에는 수동, 자동 두 가지가 존재합니다.

 

자동 Bean 등록(@ComponentScan, @Component)

Spring이 클래스에 붙은 annotation을 보고 자동으로 Bean으로 등록합니다.

 

 

예시코드

// myService 라는 이름의 Spring Bean
@Component
public class MyService {

    public void doSomething() {
        System.out.println("Spring Bean 으로 동작");
    }
    
}
@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {}
  • `@ComponentScan`을 통해 `@Component`로 설정된 클래스를 찾아서 자동으로 IoC 컨테이너에 Bean으로 등록해줍니다.
    • @Component`가 있는 클래스의 앞글자만 소문자로 변경하여 Bean 이름으로 등록합니다.
    • 단, `@ComponentScan`이 지정된 패키지 내에 있어야 등록됩니다.

 

장점

  • 코드가 간결하고 편리합니다

단점

  • Bean 이름 충돌 등 세밀한 제어가 어렵습니다.
  • 외부 라이브러리의 클래스는 직접 제어가 불가합니다.

 


 

수동 Bean 등록(@Configuration, @Bean)

개발자가 직접 Java 설정 코드를 통해 Bean을 등록합니다.

 

 

예시 코드

// 인터페이스
public interface TestService {
    void doSomething();
}

// 인터페이스 구현체
public class TestServiceImpl implements TestService {
    @Override
    public void doSomething() {
        System.out.println("Test Service 메서드 호출");
    }
}

// 수동으로 빈 등록
@Configuration
public class AppConfig {
    
    // TestService 타입의 Spring Bean 등록
    @Bean
    public TestService testService() {
        // TestServiceImpl을 Bean으로 등록
        return new TestServiceImpl();
    }
    
}

// Spring Bean으로 등록이 되었는지 확인
public class MainApp {
    public static void main(String[] args) {
        // Spring ApplicationContext 생성 및 설정 클래스(AppConfig) 등록
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

        // 등록된 TestService 빈 가져오기
        TestService service = context.getBean(TestService.class);

        // 빈 메서드 호출
        service.doSomething();
    }
}
  • `@Configuration`이 있는 클래스를 Bean으로 등록하고 해당 클래스를 파싱해서 `@Bean`이 있는 메서드를 찾아 Bean을 생성합니다. 이때 해당 메서드의 이름으로 Bean의 이름이 설정됩니다.
  • 수동으로 Bean을 등록할 때는 항상 `@Configuration`과 함께 사용해야 Bean이 싱글톤으로 관리됩니다.

 

더보기

세밀한 과정

 

1. 설정 클래스 정의 : 먼저 `@Configuration` annotaion이 붙은 설정 클래스를 정의합니다.

@Configuration
public class AppConfig {
    // Bean 등록은 여기서!
}
  • `@Configuration`은 Spring에게 "이 클래스는 Bean 설정을 위한 클래스야"라고 알려줍니다.
  • `@Configuration` 클래스는 Spring이 프록시 객체(CGLIB)를 생성해서 관리합니다.
    • 내부적으로 CGLIB 프록시를 이용해 싱글턴 유지 및 라이프사이클 제어를 합니다.

 

2. `@Bean` 어노테이션 사용하여 메서드 정의

@Bean
public MemberService memberService() {
    return new MemberService(memberRepository());
}
  • `@Bean` 어노테이션이 붙은 메서드는 반환된 객체를 Spring 컨테이너가 관리하는 Bean으로 등록합니다.
  • 메서드 이름이 Bean 이름이 되며, `@Bean(name="customName")`으로 이름 지정도 가능합니다.

 

3. Spring 컨테이너에 등록 : Spring이 설정 클래스를 읽는 순간 다음 일이 일어납니다:

  1. 설정 클래스 스캔 (`@Configuration`)
  2. `@Bean` 메서드 실행
  3. 메서드 반환값을 Bean으로 등록 (빈 이름 = 메서드명)
  4. Bean 간 의존성 자동 주입 (매개변수/호출 순서를 분석해서)

 

4. 싱글톤 유지

@Bean
public A a() {
    return new A();
}

@Bean
public B b() {
    return new B(a()); // 이때 a()는 한 번만 실행됨
}

 

  • `@Configuration` 클래스는 내부적으로 프록시(CGLIB)를 사용해 `@Bean` 메서드가 여러 번 호출되어도 항상 같은 객체를 반환합니다.
  • 즉, Spring은 자동으로 싱글턴 보장을 해줍니다.

 

 

 

 장점

  • Bean 이름, 스코프, 생성 방식 등을 정밀하게 제어 가능합니다.
  • 외부 라이브러리 클래스도 등록 가능합니다.

 단점

  • 코드가 길고 복잡해질 수 있습니다.
  • 자동 등록보다 생산성이 떨어집니다.