[Springboot] Spring Bean이란?

건희·2025년 6월 22일

[Spring Boot] Spring Bean이란?

목차

  1. Spring Bean이란?
  2. Spring Bean의 특징
  3. Spring Bean의 생명주기
  4. Spring Bean 등록 방법
  5. Spring Bean 스코프
  6. 실제 예제로 이해하기
  7. Spring Bean의 장점

Spring Bean이란?

Spring Bean은 Spring IoC(Inversion of Control) 컨테이너가 관리하는 객체를 의미한다. 쉽게 말해서, Spring이 생성하고 관리하는 모든 객체를 Spring Bean이라고 한다.

핵심 개념

  • IoC 컨테이너: Spring이 객체의 생성과 의존성을 관리하는 컨테이너
  • Bean: IoC 컨테이너가 관리하는 객체
  • 의존성 주입(DI): Bean들 간의 의존성을 Spring이 자동으로 주입

Spring Bean의 특징

1. 싱글톤 패턴 (기본값)

  • 하나의 Bean 인스턴스만 생성되어 재사용
  • 메모리 효율성과 성능 향상

2. 의존성 주입

  • Bean 간의 의존성을 Spring이 자동으로 관리
  • 느슨한 결합(Loose Coupling) 구현

3. 생명주기 관리

  • Spring이 Bean의 생성, 초기화, 소멸을 관리
  • @PostConstruct, @PreDestroy 등으로 생명주기 제어

Spring Bean의 생명주기

1. Bean 정의 로드
   ↓
2. Bean 인스턴스 생성
   ↓
3. 의존성 주입
   ↓
4. 초기화 (@PostConstruct)
   ↓
5. Bean 사용
   ↓
6. 소멸 (@PreDestroy)

Spring Bean 등록 방법

1. 어노테이션 기반 등록

@Component 계열

@Component          // 기본 컴포넌트
@Service           // 서비스 계층
@Repository        // 데이터 접근 계층
@Controller        // 웹 컨트롤러
@RestController    // REST API 컨트롤러

예시

@Service
public class UserService {
    private final UserRepository userRepository;
    
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}

2. @Bean 메서드로 등록

@Configuration
public class AppConfig {
    
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

3. XML 설정 (레거시)

<bean id="userService" class="com.example.service.UserService">
    <constructor-arg ref="userRepository"/>
</bean>

Spring Bean 스코프

1. Singleton (기본값)

  • IoC 컨테이너당 하나의 인스턴스
  • 모든 요청에서 동일한 객체 공유

2. Prototype

  • 요청할 때마다 새로운 인스턴스 생성
  • 상태를 가진 객체에 적합

3. Request

  • HTTP 요청마다 새로운 인스턴스
  • 웹 애플리케이션에서만 사용

4. Session

  • HTTP 세션마다 새로운 인스턴스
  • 사용자별 상태 관리

5. Application

  • ServletContext마다 하나의 인스턴스
  • 웹 애플리케이션 전체에서 공유

스코프 설정 예시

@Component
@Scope("prototype")
public class PrototypeBean {
    // 매번 새로운 인스턴스 생성
}

@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestScopedBean {
    // HTTP 요청마다 새로운 인스턴스
}

실제 예제로 이해하기

프로젝트 구조

src/main/java/com/example/demospringboot/
├── controllers/
│   └── UserController.java
├── services/
│   └── UserService.java
├── repositories/
│   └── UserRepository.java
└── config/
    └── AppConfig.java

1. Controller Bean

@RestController
@RequestMapping("/api/users")
public class UserController {
    
    private final UserService userService;
    
    // 생성자 주입 - Spring이 UserService Bean을 자동 주입
    public UserController(UserService userService) {
        this.userService = userService;
    }
    
    @GetMapping("/{id}")
    public ResponseEntity<User> getUser(@PathVariable Long id) {
        User user = userService.findById(id);
        return ResponseEntity.ok(user);
    }
}

2. Service Bean

@Service
public class UserService {
    
    private final UserRepository userRepository;
    
    // 생성자 주입 - Spring이 UserRepository Bean을 자동 주입
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
    public User findById(Long id) {
        return userRepository.findById(id)
            .orElseThrow(() -> new RuntimeException("User not found"));
    }
}

3. Repository Bean

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    // Spring Data JPA가 자동으로 구현체 생성
    // 이 인터페이스 자체가 Spring Bean으로 등록됨
}

4. Configuration Bean

@Configuration
public class AppConfig {
    
    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        
        // HTTP 요청/응답 로깅 설정
        restTemplate.setInterceptors(Arrays.asList(
            new LoggingInterceptor()
        ));
        
        return restTemplate;
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

5. Bean 사용 예시

@Service
public class ExternalApiService {
    
    private final RestTemplate restTemplate;
    
    // AppConfig에서 정의한 RestTemplate Bean이 주입됨
    public ExternalApiService(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }
    
    public WeatherInfo getWeather(String city) {
        String url = "https://api.weatherapi.com/v1/current.json?key=YOUR_KEY&q=" + city;
        return restTemplate.getForObject(url, WeatherInfo.class);
    }
}

Spring Bean의 장점

1. 의존성 관리 자동화

  • 객체 간의 의존성을 Spring이 자동으로 관리
  • 개발자가 직접 객체를 생성하고 연결할 필요 없음

2. 싱글톤 패턴 자동 적용

  • 메모리 효율성 향상
  • 일관된 상태 관리

3. 생명주기 관리

  • Bean의 생성, 초기화, 소멸을 Spring이 관리
  • 리소스 관리 자동화

4. 테스트 용이성

  • Mock 객체 주입이 쉬움
  • 단위 테스트 작성이 간편

5. 설정의 중앙화

  • 애플리케이션의 모든 객체 설정을 한 곳에서 관리
  • 유지보수성 향상

마무리

Spring Bean은 Spring Framework의 핵심 개념으로, 객체의 생성과 의존성 관리를 Spring이 담당하게 함으로써 개발자가 비즈니스 로직에만 집중할 수 있게 해줌.

핵심 포인트:

  • Spring Bean = Spring이 관리하는 객체
  • IoC 컨테이너가 Bean의 생명주기를 관리
  • 의존성 주입을 통해 느슨한 결합 구현
  • 어노테이션 기반으로 간편하게 Bean 등록

Spring Boot에서는 @ComponentScan을 통해 자동으로 Bean을 스캔하고 등록하므로, 개발자는 비즈니스 로직 구현에만 집중할 수 있음.

profile
💻 🍎

0개의 댓글