게으른 개발자의 끄적거림

Spring @Component @Bean 완벽 정리

끄적잉 2025. 3. 15. 00:30

Spring @Component 어노테이션과 빈(Bean)에 대한 상세 설명

 

1. @Component 어노테이션이란?

@Component는 Spring 프레임워크에서 특정 클래스를 Spring의 관리 대상 객체(빈, Bean) 로 등록하는 어노테이션이다. 이 어노테이션을 사용하면 해당 클래스가 자동으로 Spring의 IoC(Inversion of Control, 제어의 역전) 컨테이너에 의해 관리된다.

Spring에서는 @Component를 사용하여 수동으로 빈을 등록하는 대신, 자동으로 빈을 감지하고 등록할 수 있다. 이는 Spring의 컴포넌트 스캔(Component Scanning) 기능을 이용하는 것으로, @Component가 붙은 클래스는 자동으로 스캔되어 스프링 컨테이너에 등록된다.


2. @Component의 동작 원리

Spring이 @Component를 사용하여 빈을 등록하는 과정은 다음과 같다.

  1. @Component 어노테이션이 붙은 클래스를 찾아 빈으로 등록한다.
  2. Spring의 컴포넌트 스캔(Component Scan) 기능이 @Component가 선언된 클래스를 감지한다.
  3. 감지된 클래스는 Spring 컨테이너(ApplicationContext) 에 의해 빈으로 관리된다.
  4. 다른 곳에서 @Autowired 등을 사용하여 해당 빈을 주입받아 사용할 수 있다.

3. @Component 사용 방법

(1) 기본적인 사용법

@Component를 클래스에 붙이면 해당 클래스가 빈으로 등록된다.

import org.springframework.stereotype.Component;

@Component
public class MyComponent {
    public void doSomething() {
        System.out.println("MyComponent is working!");
    }
}

위의 코드를 작성하면, MyComponent 클래스는 Spring의 빈으로 등록된다.


 

(2) @ComponentScan을 이용한 컴포넌트 스캔

Spring이 @Component가 붙은 클래스를 자동으로 찾기 위해서는 컴포넌트 스캔을 활성화해야 한다.

@ComponentScan을 사용하여 특정 패키지를 스캔할 수 있다.

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = "com.example.myapp") // 해당 패키지에서 @Component를 찾음
public class AppConfig {
}

위 설정을 하면 com.example.myapp 패키지 내의 @Component가 붙은 클래스들이 자동으로 빈으로 등록된다.


4. @Component 관련 어노테이션

Spring에서는 @Component를 확장한 여러 가지 어노테이션이 제공된다.

(1) @Service

  • 서비스 계층(Service Layer) 을 나타내는 어노테이션.
  • 일반적으로 비즈니스 로직을 담당하는 클래스에 사용된다.
import org.springframework.stereotype.Service;

@Service
public class MyService {
    public String getServiceInfo() {
        return "Service Layer is working!";
    }
}

(2) @Repository

  • DAO(Data Access Object) 계층을 나타내는 어노테이션.
  • 데이터베이스 관련 작업을 수행하는 클래스에서 사용된다.
import org.springframework.stereotype.Repository;

@Repository
public class MyRepository {
    public String getData() {
        return "Fetching data from database!";
    }
}

 

(3) @Controller

  • Spring MVC의 컨트롤러 역할을 하는 클래스에 사용된다.
  • 주로 HTTP 요청을 처리하는 웹 애플리케이션에서 사용된다.
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/home")
public class MyController {

    @GetMapping
    @ResponseBody
    public String home() {
        return "Hello from Controller!";
    }
}

 

 

5. 빈(Bean)과 IoC 컨테이너

(1) 빈(Bean)이란?

  • Spring에서 관리하는 객체를 빈(Bean)이라고 한다.
  • 개발자가 객체를 직접 생성하는 것이 아니라, Spring이 객체를 생성하고 관리한다.
  • Bean의 생성, 의존성 주입(Dependency Injection), 생명주기 관리는 모두 Spring이 담당한다.

(2) IoC(Inversion of Control, 제어의 역전) 컨테이너란?

  • 객체의 생성과 관리를 개발자가 직접 하는 것이 아니라 Spring이 대신 담당하는 개념.
  • Spring 컨테이너가 자동으로 빈을 생성하고, 의존성을 주입해준다.
  • ApplicationContext와 BeanFactory가 대표적인 IoC 컨테이너이다.

6. @Component와 빈 주입(Dependency Injection)

Spring이 관리하는 빈을 다른 클래스에서 사용하려면 의존성 주입(Dependency Injection) 이 필요하다.

(1) @Autowired를 이용한 빈 주입

Spring에서는 @Autowired를 사용하여 자동으로 빈을 주입할 수 있다.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MyService {
    public String getMessage() {
        return "Hello from MyService!";
    }
}

@Component
public class MyController {
    
    private final MyService myService;

    @Autowired // 자동으로 MyService 빈을 주입
    public MyController(MyService myService) {
        this.myService = myService;
    }

    public void showMessage() {
        System.out.println(myService.getMessage());
    }
}

 

 

(2) 생성자 주입 vs 필드 주입

생성자 주입 권장:

  • 테스트하기 용이하고, 불변성을 보장할 수 있다.
  • @Autowired 없이도 Spring 4.3 이상에서는 생성자에 한해서 자동 주입된다.

필드 주입:

  • 코드가 간결하지만, 변경이 어렵고 테스트가 어려울 수 있다.
@Component
public class MyController {

    @Autowired
    private MyService myService; // 필드 주입 (권장되지 않음)
}

7. @Component를 사용한 실제 예제

아래는 @Component를 이용하여 간단한 애플리케이션을 구성하는 예제이다.

(1) 서비스 클래스 (@Service 사용)

import org.springframework.stereotype.Service;

@Service
public class GreetingService {
    public String getGreeting() {
        return "Hello, Spring!";
    }
}

(2) 컨트롤러 클래스 (@Component 사용)

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class GreetingController {
    private final GreetingService greetingService;

    @Autowired
    public GreetingController(GreetingService greetingService) {
        this.greetingService = greetingService;
    }

    public void printGreeting() {
        System.out.println(greetingService.getGreeting());
    }
}

 

 

 

(3) 애플리케이션 실행

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainApplication {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext("com.example");

        GreetingController controller = context.getBean(GreetingController.class);
        controller.printGreeting();
    }
}

8. 결론

  • @Component는 Spring이 자동으로 객체를 관리할 수 있도록 하는 어노테이션이다.
  • @Service, @Repository, @Controller는 @Component를 확장한 개념으로 각각 서비스, 데이터 액세스, 컨트롤러 역할을 한다.
  • Spring의 IoC 컨테이너는 빈을 관리하며, @Autowired 등을 통해 빈을 주입받을 수 있다.
  • @ComponentScan을 사용하면 지정된 패키지 내에서 자동으로 빈을 등록할 수 있다.