개발은 재밌어야 한다
article thumbnail
반응형

스프링 프레임워크에서는 객체를 관리하고, 필요한 곳에 자동으로 주입하는 의존성 주입(Dependency Injection, DI) 을 통해 의존성을 주입할 수 있습니다. 이 글에서는 스프링에서 @Configuration, @Bean, @Component, @Service, @Repository와 같은 어노테이션을 활용하여 Bean을 등록하고 관리하는 방법에 대해 설명하겠습니다.

스프링에서 Bean이란?

스프링에서 Bean은 스프링 컨테이너가 관리하는 객체를 의미합니다. 이러한 Bean은 스프링의 DI(Dependency Injection)를 통해 의존 관계를 해결하고, 객체 간의 연결을 관리합니다.

 

스프링에서 Bean 등록 방법

@Configuration

@Configuration 어노테이션은 스프링 프레임워크에서 설정 클래스를 정의하는 데 사용되는 어노테이션입니다. 이 어노테이션이 붙은 클래스는 스프링 컨테이너에서 Bean을 정의하는 역할을 합니다. 즉, @Configuration이 붙은 클래스는 스프링 설정 파일로 작동하며, 이 클래스 내에서 @Bean 어노테이션을 사용하여 Bean을 등록하거나, @ComponentScan을 사용하여 컴포넌트 스캔을 설정할 수 있습니다.

@Configuration
public class AppConfig {

    @Bean
    public MyService myService() {
        return new MyServiceImpl();
    }
}

 

  • @Configuration의 주요 역할:
    1. Bean 정의: @Configuration 클래스는 @Bean 메서드를 통해 Bean을 등록하는 역할을 합니다. @Bean 어노테이션을 사용하여 객체를 직접 생성하고, 이를 스프링 컨테이너에 등록합니다.
    2. 스프링 설정 클래스: 이 클래스는 스프링 애플리케이션의 설정을 정의하는 역할을 합니다. XML 기반 설정 대신, 자바 기반의 설정을 사용하려는 경우 @Configuration을 사용합니다.
    3. 싱글톤 보장: @Configuration이 붙은 클래스는 싱글톤으로 관리됩니다. 즉, @Bean으로 등록한 객체는 스프링 컨테이너에서 하나만 존재하며, 같은 객체를 여러 곳에서 참조할 수 있습니다.
@Configuration
public class AppConfig {

    @Bean
    public MyService myService() {
        return new MyServiceImpl();
    }

    @Bean
    public MyRepository myRepository() {
        return new MyRepositoryImpl();
    }
}

 

위 코드에서 AppConfig 클래스는 @Configuration 어노테이션을 사용하여 설정 클래스를 정의하고 있습니다. 이 클래스는 @Bean 메서드를 통해 MyService와 MyRepository 객체를 스프링 컨테이너에 등록합니다. 스프링은 이 메서드를 호출하여 객체를 생성하고, 필요한 곳에서 이를 자동으로 의존성 주입할 수 있습니다.

@Configuration과 @Component의 차이점

  • @Component는 일반적인 Bean을 등록하는 데 사용되며, 스프링이 자동으로 해당 클래스를 스캔하여 Bean으로 등록합니다.
  • @Configuration은 설정 클래스를 나타내며, @Bean 메서드를 통해 Bean을 정의합니다. 이 클래스는 스프링 컨테이너에 의해 특별하게 처리되어, 내부에서 @Bean을 사용하는 메서드가 항상 하나의 객체만 반환하도록 보장합니다.
반응형

@Component, @Service, @Repository

@Component, @Service, @Repository는 클래스 수준에서 Bean을 등록할 때 사용하는 어노테이션입니다. 이들 모두 @Component를 확장한 어노테이션이며, 스프링이 이 클래스를 자동으로 Bean으로 등록하도록 합니다.

 

@Component

@Component는 가장 일반적인 Bean 등록 어노테이션입니다. 특정 기능에 맞는 별도의 어노테이션이 없다면 @Component를 사용하여 클래스를 Bean으로 등록할 수 있습니다.

@Component
public class MyComponent {
    public void doSomething() {
        System.out.println("Doing something...");
    }
}

 

@Service와 @Repository

@Service는 서비스 계층에, @Repository는 데이터 접근 계층에 적합한 Bean 등록 어노테이션입니다. 이 두 어노테이션은 기능상 @Component와 동일하지만, 의미적으로 구분을 두기 위해 사용됩니다.

@Service
public class MyService {
    public void serve() {
        System.out.println("Service is working...");
    }
}

@Repository
public class MyRepository {
    public void save() {
        System.out.println("Saving data...");
    }
}

 

의존성 주입(Dependency Injection)

스프링의 핵심 기능 중 하나는 의존성 주입입니다. 이를 통해 클래스 간의 결합도를 낮추고, 객체들을 자동으로 주입받을 수 있습니다. 주입 방법에는 생성자 주입, 필드 주입, 세터 주입 등이 있습니다.

 

생성자 주입

@Component
public class MyComponent {
    private final MyService myService;

    // 생성자 주입
    @Autowired
    public MyComponent(MyService myService) {
        this.myService = myService;
    }
}

생성자 주입은 객체 생성 시 의존성이 모두 주입되므로, 불변성을 보장하고, 테스트 코드 작성에 유리합니다.

 

필드 주입

@Component
public class MyComponent {
    @Autowired
    private MyService myService;
}

필드 주입은 코드가 간결하지만, 테스트가 어려울 수 있으며, @Autowired를 사용할 때 필드에 주입되는 의존성을 관리하기 어렵습니다.

 

세터 주입

@Component
public class MyComponent {
    private MyService myService;

    @Autowired
    public void setMyService(MyService myService) {
        this.myService = myService;
    }
}

세터 주입은 객체가 생성된 후 의존성이 주입되므로, 순환 의존성을 해결할 때 유용할 수 있습니다. 하지만 불변성을 보장할 수 없습니다.

 

컴포넌트 스캔과 자동 Bean 등록

스프링은 기본적으로 컴포넌트 스캔(Component Scan) 을 통해 @Component, @Service, @Repository, @Controller와 같은 어노테이션이 붙은 클래스를 자동으로 Bean으로 등록합니다. 이를 통해 설정 파일에서 직접 @Bean을 선언하지 않아도, 특정 패키지 내의 클래스들은 자동으로 Bean으로 등록됩니다.

@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
    // com.example 패키지 내의 모든 @Component 클래스들이 Bean으로 등록됨
}

 

반응형
profile

개발은 재밌어야 한다

@ghyeong

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!