"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > Spring Framework의 제어 반전

Spring Framework의 제어 반전

2024-11-06에 게시됨
검색:861

Inversion of Control in Spring Framework

제어 반전(IoC)과 종속성 주입(DI)은 Spring Framework의 두 가지 기본 개념입니다. 전통적으로 객체는 자신의 종속성을 생성하고 관리하는 역할을 담당합니다. 그러나 IoC는 객체 생성 및 종속성 관리 제어를 Spring과 같은 프레임워크에 넘겨줌으로써 이러한 책임을 뒤집습니다.

이러한 변화는 다음과 같은 몇 가지 이점을 제공합니다.

  • 간편한 구현 교체: 코드베이스를 최소한으로 변경하면서 다양한 구현을 교체할 수 있습니다.
  • 모듈성 증가: 애플리케이션 구성 요소가 더욱 모듈화되어 문제 분리가 용이해졌습니다.
  • 향상된 테스트 가능성: 구성 요소를 별도로 테스트할 수 있으므로 모의 작업 및 기타 테스트 전략이 단순화됩니다.

IoC는 팩토리 패턴, 전략 패턴, 서비스 로케이터 패턴과 같은 디자인 패턴을 포함한 다양한 메커니즘을 통해 구현될 수 있습니다. 그러나 IoC를 달성하는 가장 일반적이고 강력한 방법은 종속성 주입을 이용하는 것입니다.

종속성 주입 이해

종속성 주입(DI)은 종속성 자체를 생성하는 객체가 아닌 프레임워크가 객체에 종속성을 주입하는 기술입니다. Spring에는 다양한 유형의 DI가 있습니다:

  • 생성자 주입: 클래스의 생성자를 통해 종속성을 제공합니다.
  • 세터 주입: 종속성은 세터 메서드를 통해 주입됩니다.
  • 필드 주입: 주석을 사용하여 종속성을 필드에 직접 할당합니다.

예를 들어 간단한 서비스 클래스에서는 다음과 같은 내용을 볼 수 있습니다.

@Service
public class OrderService {

    private final PaymentService paymentService;

    @Autowired
    public OrderService(PaymentService paymentService) {
        this.paymentService = paymentService;
    }

    public void processOrder(Order order) {
        paymentService.processPayment(order.getPaymentDetails());
    }
}

여기서 PaymentService는 생성자 주입을 통해 OrderService에 주입되는데, 이는 명확한 종속성과 테스트 용이성 때문에 일반적으로 선호됩니다.

IoC 컨테이너: BeanFactory 대 ApplicationContext

Spring은 빈(Spring이 관리하는 객체)의 라이프사이클을 관리하는 IoC 컨테이너를 제공합니다. 이 컨테이너의 기본 인터페이스는 BeanFactory입니다. 그러나 대부분의 애플리케이션은 BeanFactory를 확장하고 추가 기능을 제공하는 ApplicationContext를 사용합니다.

콩공장

  • 기본 IoC 컨테이너: Bean을 생성하고 관리하는 기본 기능을 제공합니다.
  • 지연 초기화: Bean은 처음 요청될 때 생성됩니다.

애플리케이션컨텍스트

  • 고급 IoC 컨테이너: BeanFactory의 기본 기능 외에도 다음을 제공합니다.
    • 국제화(i18n) 지원
    • 이벤트 전파 및 처리
    • 비동기 요청 처리
    • 관점 지향 프로그래밍(AOP)과 통합
  • 즉시 초기화: 애플리케이션이 시작될 때 Bean을 인스턴스화하여 즉시 사용할 수 있습니다.

예:

// Getting a bean from the ApplicationContext
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
MyBean myBean = context.getBean(MyBean.class);

이 예에서 ApplicationContext는 Bean을 검색하는 데 사용됩니다. 기본 BeanFactory를 사용하고 있다면 유사한 기능을 제공하지만 ApplicationContext의 추가 이점은 없습니다.

ApplicationContext에 접근하기

현재 ApplicationContext에 액세스하는 두 가지 일반적인 방법이 있습니다.

  1. Autowired: ApplicationContext를 컴포넌트에 직접 주입합니다.

    @Autowired
    private ApplicationContext applicationContext;
    
  2. ApplicationContextAware: 필요에 따라 ApplicationContext를 검색할 수 있는 ApplicationContextAware 인터페이스를 구현합니다.

    public class MyBean implements ApplicationContextAware {
        private ApplicationContext applicationContext;
    
        @Override
        public void setApplicationContext(ApplicationContext context) throws BeansException {
            this.applicationContext = context;
        }
    }
    

Spring 애플리케이션의 라이프사이클

Spring 애플리케이션이 시작되면 일련의 단계가 수행됩니다.

  1. 환경 변수 및 속성 처리: application.properties 또는 application.yml의 설정을 통합하여 환경 개체가 생성됩니다.

  2. ApplicationContext 생성: 적절한 ApplicationContext 유형이 결정되고 인스턴스화됩니다. 예를 들어 Spring Boot 애플리케이션은 Java 기반 구성에 AnnotationConfigServletWebServerApplicationContext를 사용할 수 있습니다.

  3. 빈 정의 로드: Spring은 주석이 달린 클래스, @Configuration 클래스 또는 XML 파일과 같은 여러 소스에서 빈 정의를 로드합니다. 각 Bean 정의에는 Bean의 유형, 범위, 종속성 및 수명주기 콜백에 대한 정보가 포함됩니다.

  4. BeanFactoryPostProcessors 처리: 이 프로세서는 실제 빈이 생성되기 전에 빈 정의를 수정합니다.

  5. 종속성 해결 및 Bean 생성: ApplicationContext는 종속성을 해결하고 Bean을 생성합니다. Bean이 다른 Bean에 대한 종속성을 갖는 경우 해당 종속성이 먼저 생성됩니다.

봄의 콩 스코프

Spring은 컨테이너 내 빈의 수명주기와 가시성을 정의하는 다양한 빈 범위를 지원합니다.

  • 싱글톤(기본값): 전체 애플리케이션 컨텍스트에 대해 Bean의 단일 인스턴스가 생성됩니다.
  • 프로토타입: Bean이 요청될 때마다 새 인스턴스가 생성됩니다.
  • 요청: 각 HTTP 요청(웹 애플리케이션)에 대해 새 Bean 인스턴스가 생성됩니다.
  • 세션: 각 HTTP 세션(웹 애플리케이션)마다 새 Bean 인스턴스가 생성됩니다.

예:

@Bean
@Scope("prototype")
public MyPrototypeBean myPrototypeBean() {
    return new MyPrototypeBean();
}

이 예에서는 컨테이너에서 요청될 때마다 새로운 MyPrototypeBean 인스턴스가 생성됩니다.

Bean 범위의 프록시 객체

싱글톤 범위의 Bean이 프로토타입 범위의 Bean에 의존하는 시나리오를 생각해 보세요. 일반적으로 프로토타입 빈은 싱글톤 초기화 중에 한 번만 생성됩니다. 프로토타입 빈의 새로운 인스턴스가 매번 제공되도록 보장하기 위해 Spring은 프록시 객체를 사용합니다.

프록시의 예:

@Component
@Scope(value = "singleton")
public class SingletonBean {

    @Autowired
    @Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
    private PrototypeBean prototypeBean;

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

여기서 ScopedProxyMode.TARGET_CLASS는 getMessage()가 호출될 때마다 새 PrototypeBean 인스턴스가 반환되도록 보장합니다.

스프링 프레임워크와 스프링 부트의 차이점

Spring Boot는 새로운 Spring 애플리케이션의 설정과 개발을 단순화하는 Spring Framework의 확장입니다. 다음을 제공합니다:

  • 임베디드 애플리케이션 서버: Tomcat, Jetty 또는 Undertow가 내장된 독립형 앱으로 Spring 애플리케이션을 쉽게 실행할 수 있습니다.
  • 자동 구성: 클래스 경로 및 기타 설정을 기반으로 Bean을 자동으로 구성합니다.
  • 간소화된 패키징: 애플리케이션을 실행 가능한 JAR 또는 WAR로 패키징합니다.
  • 통합 모니터링 및 상태 확인: 애플리케이션의 상태를 모니터링하기 위한 내장 엔드포인트입니다.

Spring Boot의 자동 구성

자동 구성은 클래스 경로의 종속성을 기반으로 많은 항목을 구성하는 Spring Boot의 강력한 기능입니다. 이는 다음과 같은 조건부 주석으로 제어됩니다:

  • @ConditionalOnClass
  • @ConditionalOnMissingClass
  • @ConditionalOnBean
  • @ConditionalOnMissingBean

예:

예를 들어 클래스 경로에 Jackson이 있으면 Spring Boot는 JSON 직렬화를 위해 자동으로 ObjectMapper를 구성합니다.

@Configuration
@ConditionalOnClass(ObjectMapper.class)
public class JacksonAutoConfiguration {
    // Configuration details...
}

ObjectMapper가 있으면 이 구성이 자동으로 적용됩니다. 그렇지 않으면 건너뜁니다.

활성 자동 구성 보기

application.properties에 다음을 추가하여 시작 중에 활성 자동 구성을 기록할 수 있습니다.

logging.level.org.springframework.boot.autoconfigure=DEBUG

이렇게 하면 적용된 구성과 적용되지 않은 구성을 보여주는 자세한 보고서가 생성되어 애플리케이션 구성의 문제를 해결하거나 이해하는 데 도움이 됩니다.

결론

제어 반전 및 종속성 주입은 Spring을 강력하게 만드는 유연성, 모듈성 및 테스트 가능성을 가능하게 하는 핵심 개념입니다. Spring의 IoC 컨테이너 작동 방식, Bean 관리 방식, Spring Boot가 이러한 기능을 확장하는 방식을 이해함으로써 강력하고 유지 관리 가능한 애플리케이션을 보다 효율적으로 개발할 수 있습니다.

릴리스 선언문 이 글은 https://dev.to/be11amer/inversion-of-control-in-spring-framework-4mc0?1 에서 복제되었습니다. 침해 내용이 있는 경우, [email protected]으로 연락하여 삭제하시기 바랍니다.
최신 튜토리얼 더>

부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.

Copyright© 2022 湘ICP备2022001581号-3