Programming/Spring Framework 주요 개념

스프링 IoC 컨테이너와 빈 (스프링 핵심 기술 - 1)

흠냐아뤼 2020. 3. 4. 01:16
728x90

 

1. 스프링 프레임워크의 디자인 철학

- 모든 선택은 개발자의 몫 (특정 기술을 강요하지 않음)

- 다양한 관점을 지향한다 (유연성)

- 하위 호환성을 지킨다 (노력)

- API를 신중하게 설계한다 (공들인다)

- 높은 수준의 코드를 지향한다

 

 

2. IoC  (Inversion of Control)

- 의존 관계 주입(Dependency Injection)이라고도 하며, 어떤 객체가 사용하는 의존 객체를 직접 만들어 사용하는 것이 아니라, 주입 받아 사용하는 방법을 말한다.

- 가장 핵심이되는 최상위 인터페이스는 BeanFactory. 이의 하위 인터페이스는 ApplicationContext (BeanFactory + 다양한 기능이 추가됨)

 

 

3. 빈(Bean)

- IoC 컨테이너가 관리하는 객체

- 빈으로 등록되면 좋은 장점

  1. 기본적으로 싱글톤 Scope로 등록됨 (싱글톤 <-> 프로토타입) (매번 만드는 프로토타입보다, 메모리 적으로도 효율적이고, 런 타임 시에 성능 최적화에 유리함)
  2. 라이프사이클 인터페이스 제공하며, 이를 사용해 다양한 작업 가능

 

 

4. 빈을 등록하는 방법

- xml에 직접 빈을 등록

- xml에서 component-scan을 하고, Annotation 기반으로 빈을 등록

- 자바 설정 파일에서 빈을 등록

@Configuration
public class ApplicationConfig {

    @Bean
    public BookRepository bookRepository(){
        return new BookRepository();
    }

    @Bean
    public BookService bookService(){
        BookService bookService = new BookService();
        // 직접 의존성 주입
        bookService.setBookRepository(bookRepository());
        return bookService;
    }
}

- 자바 설정 파일에서 component-scan을 등록 하고, Annotation 기반으로 빈을 등록

@Configuration
@ComponentScan(basePackageClasses = DemoApplication.class)
public class ApplicationConfig {
}

- Spring Boot 프로젝트일 경우, @SpringBootApplication Annotation과 @Component Annotation 기반으로 빈을 등록

 

 

참고) Annotation 정리

@Component:  @Service, @Repository, @Controller에 해당하진 않지만 빈으로 등록하고 싶을 때 사용

@Repository: 데이터를 다루는 빈을 등록할 때

@Service: 서비스 클래스에 사용

@Controller / @RestController:  컨트롤러에 사용

@Configuration: 빈 설정 파일에 사용

 

 

5. 의존성 주입 (@AutoWire)

필요한 의존 객체의 '타입'에 해당하는 빈을 찾아 주입한다.

@AutoWire(Required = false)

 

사용할 수 있는 위치

- 생성자 (추천하는 방법, Annotation 생략 가능)

- 세터

- 필드

 

같은 빈 타입이 여러 개일 때

- @Primary 

- 해당 타입의 빈 모두 주입 받기 (List<>)

- @Qualifier(빈 이름)  (추천하지 않는 방식)

 

BeanPostProcessor 라이프사이클의 인터페이스를 구현체에 의해 동작함

- @PostConstruct (빈 객체가 만들어진 후 실행됨)

 

 

6. @Component와 컴포넌트 스캔

스캔 위치를 설정(패키지 또는 클래스 이름)하고, 필터를 통해 스캔을 제외시킬 수 있음

실행 성능이 좋은 펑션을 사용한 빈 등록이 있지만, 컴포넌트 스캔을 대체하여 너무 많은 빈들을 일일이 등록하여 사용하는 것에는 불편하다는 단점이 있음

 

 

7. Bean의 Scope

- 싱글톤

- 프로토타입 (Request, Session, WebSocket...)

 

싱글톤 빈이 프로토타입 빈을 참조하면 -> 프로토타입 빈이 업데이트 안됨

- scoped-proxy

- Object-Provider (스프링 코드를 넣어야 하므로, 비추천하는 방법)

- Provider

들을 사용하여 이를 해결

 

싱글톤 객체 사용 시 주의할 점

- 프로퍼티가 공유 (Thread Safe하도록 구현해야 함)

- ApplicationContext 초기 구동 시 인스턴스 생성

 

 

8. Environment 1부 - 프로파일

프로파일이란 ? 빈들의 묶음

Envirronment의 역할은 활성화할 프로파일 확인 및 설정

각각의 환경에 따라 다른 빈들을 사용해야 하는 경우, 특정 환경에서만 빈을 등록해야 하는 경우를 위함

 

- 클래스에 정의 

- 메소드에 정의

@Configuration

@Profile("test")

 

 

9. Environment 2부 - 프로퍼티

다양한 방법으로 정의할 수 있는 설정 값

Envirronment의 역할은 프로퍼티 소스 설정 및 프로퍼티 값 가져오기

// main이 있는 클래스에 Annotation 추가
@PropertySource("classpath:/app.properties")

Environment environmnet = ctx.getEnvironment();
System.out.println(environment.getProperty("app.name"));

 

 

10. MessageSource

국제화(i18n) 기능을 제공하는 인터페이스

메시지를 다국화하는 방법

 

ApplicationContext extends MessageSource

- getMessage(String Code, Object[] args, String, default, Locale, loc)

 

스프링 부트를 사용하면, 빈 등록 없이 바로 사용 가능

- messages.properrties

- messages_ko_kr.properties

 

 

11. ApplicationEventPublisher

이벤트 프로그래밍에 필요한 인터페이스 제공. 옵저버 패턴 구현체.

 

스프링이 지향하는 점 : !비침투성!

Spring 프레임워크의 코드가 노출되지 않음

 

ApplicationContext extends ApplicationEventPublisher

- publishEvent(ApplicationEvent event)

 

1. 이벤트 객체 생성 (MyEvent)

2. 이벤트 리스너 등록 (@EventListener) (반드시, 빈 객체로 등록해야 함)

3. 이벤트 발생 (publishEvent())

 

기본적으로는 Synchronized.

순서를 정하고 싶다면 @Order와 함께 사용

비동기적으로 실행하고 싶다면 @Async와 함께 사용

 

스프링이 제공하는 기본 이벤트

- ContextRefreshedEvent : ApplicationContext를 초기화하거나 리프래시 했을 때 발생

- ContextStartedEvent : ApplicationContext를 start()하여 라이프사이클 빈들이 시작 신호를 받은 시점에 발생

- ContextStoppedEvent : ApplicationContext를 stop()하여 라이프사이클 빈들이 정지 신호를 받은 시점에 발생

- ContextClosedEvent : ApplicationContext를 close()하여 싱글톤 빈이 소멸되는 시점에 발생

- RequestHandledEvent : HTTP 요청을 처리했을 때 발생

 

 

12. ResourceLoader

리소스를 읽어오는 기능을 제공하는 인터페이스

 

ApplicationContext extends ResourceLoader

 

리소스 읽어오기

- 파일 시스템에서 읽어오기

- 클래스 패스에서 읽어오기

- URL로 읽어오기

- 상대/절대 경로로 읽어오기

 

Rescource getResource(loc)

 

 

 

인프런 백기선님 '스프링 프레임워크 핵심 기술' 강의를 들으며 정리한 내용입니다.
728x90