Spring

Spring Container와 Spring Bean

김예나 2025. 2. 5. 21:41

Spring Container

  • 스프링 애플리케이션에서 객체를 생성, 관리, 소멸하는 역할
  • Bean(Spring Container에 의해 관리되는 객체)을 생성 및 관리
  • Bean 간의 의존 관계(A객체에서 B객체를 사용하는 것)를 스프링이 설정
  • Spring Container의 최상위 인터페이스인 BeanFactory의 확장된 형태인 ApplicationContext를 의미함

-> Spring Container를 통해서 OCP, DIP 준수할 수 있음

 

Spring Bean

  • Spring Container에 의해 관리되는 객체
  • Singleton으로 설정 (= 클래스의 인스턴스가 오직 하나만 생성되도록 보장)
  • 존성 주입(DI)을 통해 다른 객체들과 의존 관계를 맺음
  • 생성, 초기화, 사용, 소멸의 생명주기

 

Spring Bean 등록방법

 

@ComponentScan : 스프링이 @이 붙은 클래스를 자동으로 검색하고 Bean으로 등록하는 기능

 

@ComponentScan 순서

  1. Spring Application이 실행되면 @ComponentScan이 지정된 패키지를 탐색
  2. @ComponentScan은 main() 메서드가 있는 클래스 상단에 @SpringBootApplication에 존재함
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
       @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

  3.  해당 패키지에서 @Component 또는 Annotation이 붙은 클래스를 찾고, Spring 컨테이너에 빈으로 등록

  4. 의존성 주입을 통해서 등록된 빈은 다른 빈과 연결됨

 

@Component 종류

@Component - 스프링에게 해당 객체를 Bean으로 등록하겠다는 의미
@Service - 스프링에게 해당 객체를 Bean으로 등록하면서 서비스 계층이라고 알리는 의미
@Repository - 스프링에게 해당 객체를 Bean으로 등록하면서 리포지토리 계층이라고 알리는 의미
@Controller - 스프링에게 해당 객체를 Bean으로 등록하면서 컨트롤러 계틍이라고 알리는 의미

 

실제로 @Service를 까보면 안에 @Component가 있음

 

Bean 충돌

  • 자동 Bean 등록 = (@ComponentScan, @Component)
    • @Component 이 있는 클래스의 앞글자만 소문자로 변경하여 Bean 이름으로 등록
    • @ComponentScan 을 통해 @Component로 설정된 클래스를 찾는 것
  • 수동 Bean 등록(@Configuration, @Bean)
    • @Configuration 이 있는 클래스를 Bean으로 등록하고 해당 클래스를 파싱해서 @Bean 이 있는 메서드를 찾아 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();
    }
}
  • 자동 Bean 등록 VS 자동 Bean 등록 충돌 : ConflictingBeanDefinitionException 발생
  • 자동 Bean 등록 VS 수동 Bean 등록 충돌 : 수동이 자동을 오버라이딩

 

Singleton Pattern

  • 클래스의 인스턴스가 오직 하나만 생성되도록 보장하는 디자인 패턴
  • 스프링 빈을 싱글톤 패턴으로 적용하지 않으면, 다수의 고객이 요청할 때마다 생성하고 소멸되기 때문에 메모리 낭비
  • 싱글톤 패턴을 직접 구현하려면 복잡하고 솔리드 원칙을 위반하게 됨 -> Spring Container는 싱글톤 패턴의 문제점들을 해결하면서 객체를 싱글톤으로 관리
  • Spring Bean은 인스턴스가 1개 이기 때문에 항상 무상태(stateless)로 설계를 해야함

IOC(제어의 역전, Inversion Of Control)

  • 객체의 생성과 관리 권한을 개발자가 아닌 Spring 컨테이너가 담당하는 것
  • (제어를 내가 아니라 프로그램이 했으니깐, 역전된 것!)

 

DI(의존성 주입, Dependency Injection)

  • 한 객체가 다른 객체를 사용할 때, 해당 객체를 직접 생성하지 않고 Spring이 주입해주는 방식
  • Spring이 객체 간의 의존성을 자동으로 주입해주는 것