본문 바로가기

Spring Boot

[Spring Boot] @Configuration @Bean 사용법

728x90

스프링에서의 @Configuration과 @Bean 어노테이션

@Configuration과 @Bean 어노테이션은 자바 기반 설정을 통해 스프링 빈을 등록하고 관리할 수 있게 하는 주요 어노테이션입니다. 이 두 어노테이션은 XML 기반 설정을 대체하여, 애플리케이션 구성을 더욱 명확하고 간결하게 만들어 코드 가독성과 유지보수성을 높입니다.

@Configuration

  • 클래스 레벨에서 사용되며, 스프링이 해당 클래스를 설정 클래스로 인식하게 합니다.
  • 클래스 내부의 @Bean 메서드가 반환하는 객체들은 싱글턴 빈으로 관리됩니다.
  • 스프링은 @Configuration이 선언된 클래스를 프록시 객체로 관리하여, 동일한 빈을 여러 번 요청하더라도 동일한 인스턴스를 반환합니다.
  • 만약 @Configuration이 없는 클래스에서 @Bean 메서드를 작성하면, 프록시 관리가 되지 않아 싱글턴 보장이 어렵습니다.

@Configuration 속성

@Target({ElementType.TYPE}) // 클래스 레벨에서만 사용 가능
@Retention(RetentionPolicy.RUNTIME) // 런타임 동안 유지되어 리플렉션을 통해 참조 가능
@Documented // Javadoc 등 문서화 시 표시됨
@Component // 스프링의 컴포넌트 스캔 대상으로 인식되도록 설정
public @interface Configuration {

    // value: @Configuration 클래스의 이름을 설정합니다.
    // proxyBeanMethods: 기본값 true. 프록시를 통해 @Bean 메서드 호출 시 싱글턴 빈 보장이 됩니다.
    // enforceUniqueMethods: 기본값 true. 중복된 메서드명이 있는 경우 예외 발생
    @AliasFor(annotation = Component.class)
    String value() default "";

    boolean proxyBeanMethods() default true;

    boolean enforceUniqueMethods() default true;
}

 

 

@Bean

  • 메서드 레벨에서 사용되며, 해당 메서드가 반환하는 객체를 스프링 빈으로 등록합니다.
  • 일반적으로 POJO 객체를 반환하며, 빈으로 등록된 객체는 스프링 컨테이너에 의해 관리됩니다.
  • @Bean 메서드를 통해 XML 설정 없이 자바 코드에서 직접 빈을 구성하고 의존성 주입을 처리할 수 있어 타입 안정성이 높아집니다.
  • 메서드 간 호출이 가능하므로, 복잡한 초기화 작업이나 다른 빈을 사용한 로직 처리가 가능합니다.

@Bean 속성

// @Bean: 메서드 레벨에서 사용하여 반환된 객체를 스프링 빈으로 등록하는 역할을 합니다.
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) // 메서드 및 어노테이션에 적용 가능
@Retention(RetentionPolicy.RUNTIME) // 런타임 동안 유지되어 리플렉션을 통해 참조 가능
@Documented // Javadoc 등 문서화 시 표시됨
public @interface Bean {

    // value, name: 빈의 이름을 설정할 수 있습니다. 기본적으로 메서드명이 빈 이름이 됩니다.
    // autowireCandidate: 기본값 true. 빈 주입 시 후보로 사용 여부를 설정합니다.
    // initMethod: 빈 초기화 시 호출할 메서드 이름을 설정합니다.
    // destroyMethod: 빈 소멸 시 호출할 메서드 이름을 설정합니다.
    @AliasFor("name")
    String[] value() default {};

    @AliasFor("value")
    String[] name() default {};

    boolean autowireCandidate() default true;

    String initMethod() default "";

    String destroyMethod() default "(inferred)";
}

 

 

사용 예제

아래 예제는 @Configuration과 @Bean을 활용하여 MyBean 클래스를 스프링 빈으로 등록하고, 이를 컨트롤러에서 사용하는 방식입니다.

MyBean.class

@Getter
public class MyBean {
    private final String message;

    public MyBean() {
        message = "shs00925 공부 블로그입니다";
    }
}
  • 빈으로 등록될 MyBean 클래스입니다. 생성자를 통해 message 값을 초기화합니다.

TestConfig.class

@Configuration
public class TestConfig {

    @Bean
    public MyBean myBean() {
        return new MyBean();
    }
}
  • @Configuration을 통해 설정 클래스를 정의하고, @Bean 메서드로 MyBean 객체를 반환하여 빈으로 등록합니다. 이 경우 myBean 메서드가 반환하는 MyBean 인스턴스가 빈으로 관리됩니다.

TestController.class

@RestController
@RequiredArgsConstructor
public class TestController {

    private final MyBean myBean;

    @GetMapping("/test")
    public String test() {
        return myBean.getMessage();
    }
}
  • TestController에서 MyBean 빈을 주입받아 /test 경로로 접근 시 MyBean의 message 값을 출력합니다.

 

 

싱글턴 빈 보장 예시

@Configuration과 @Bean의 프록시 관리로 인해 스프링 컨테이너는 같은 빈을 재사용합니다. 다음은 싱글턴 빈이 보장되는지 확인하는 예제입니다.

MyBean1.class, MyBean2.class

public class MyBean1 {
    public MyBean1() {
        System.out.println("MyBean1 생성자 호출");
    }
}

public class MyBean2 {
    public MyBean2(MyBean1 myBean1) {
        System.out.println("MyBean2 생성자 호출");
    }
}
  • MyBean1과 MyBean2 클래스는 생성자에서 호출 메시지를 출력하도록 설정했습니다. 이를 통해 빈이 몇 번 생성되는지 확인할 수 있습니다.

BeanConfig.class

@Configuration
public class BeanConfig {

    @Bean
    public MyBean1 myBean1() {
        return new MyBean1();
    }

    @Bean
    public MyBean2 myBean2() {
        return new MyBean2(myBean1());
    }
}
  • BeanConfig 설정 클래스에서 MyBean1과 MyBean2를 빈으로 등록합니다.
  • myBean2() 메서드에서 myBean1() 메서드를 호출해 MyBean1 인스턴스를 주입받도록 설정했지만, @Configuration의 프록시 기능 덕분에 MyBean1은 한 번만 생성됩니다.

TestComponent.class

@Component
@RequiredArgsConstructor
public class TestComponent {

    private final MyBean1 myBean1;
    private final MyBean2 myBean2;
}
  • TestComponent는 스프링 컨테이너에 의해 MyBean1과 MyBean2 빈을 주입받습니다. 이때 MyBean1이 싱글턴으로 보장되는지 확인할 수 있습니다.

 

요약

  • @Configuration: 설정 클래스로, 하나 이상의 @Bean 메서드를 포함하여 스프링 컨테이너에 의해 빈을 통합 관리할 수 있습니다.
  • @Bean: 특정 메서드를 빈으로 등록하며, 반환된 객체를 스프링이 관리합니다.
728x90