본문 바로가기

Spring 프레임워크/이론

Spring의 ApplicationContext, BeanFactory

2021/02/12 - [프레임워크/Spring] - Spring의 @Configuration, @Bean

 

Spring의 @Configuration, @Bean

스프링을 공부한지 얼마 안되서 아직은 모르는게 많다. 그래서 책을 읽어보면서 모르는 내용이 나오면 검색해서 알아보고 포스트를 작성하는 식으로 조금 꼼꼼하게 진행하고자 한다. 먼저 스프

haruhiism.tistory.com

지난번 포스트에서는 AnnotationConfigApplicationContext라는 것을 만들어서 Bean 객체를 받아와 메서드를 활용했다. 이 긴 이름의 객체는 ApplicationContext 인터페이스를 구현하는 클래스의 객체인데 이 인터페이스는 애플리케이션의 메시지, 환경 변수, 프로필, Bean 객체 조작 등 스프링에서 여러 중요한 역할을 맡고 있다. 애플리케이션이 실행 중일 때 접근 가능한 읽기 전용 값이며 설정 정보를 읽어 Bean 객체들을 생성, 초기화하는 역할을 수행하고 있다.

 

스프링의 핵심 기능은 객체를 생성, 초기화하는 것이기 때문에 관련된 기능이 ApplicationContext, BeanFactory 등 여러 인터페이스에 정의되어 있으며 ApplicationContext는 BeanFactory에 상속되어 있다. 그래서 ApplicationContext 인터페이스는 Bean 객체를 생성, 초기화, 보관, 제거하는 일종의 컨테이너(Container)라고 표현되기도 한다. 그냥 담기만 하는 게 아니라 Bean 객체를 생성하는 메서드(@Bean 메서드)의 이름과 Bean 객체를 연결하는 등 객체 관리를 위한 다양한 기능을 제공한다는 것이 특징이다.

 

지난 포스트에서 Bean 객체를 얻어오는데 getBean 메서드를 사용했는데 이는 BeanFactory에 정의되어 있는 메서드다. 이런 인터페이스를 기능에 따라 적절하게 구현한 클래스가 여러 가지 있는데 이는 다음과 같다.

  • AnnotationConfigApplicationContext: 자바 클래스에서 어노테이션(@)을 기반으로 객체 설정 정보를 불러오는 클래스.

  • GenericXmlApplicationContext: XML 파일에서 객체 설정 정보를 불러오는 클래스.

  • GenericGroovyApplicationContext: Groovy 코드에서 객체 설정 정보를 불러오는 클래스.

설정 정보를 읽을 파일의 타입만 다를 뿐 어쨌든 이 클래스들은 읽어 들인 설정 정보를 Bean 객체로 생성하여 보관한다. 그러면 이후 getBean 메서드로 이 객체들을 불러와서 사용할 수 있는 것이다. 그리고 이 Bean 객체들을 제공해주는 기능을 구현하기 위해 여러 가지 인터페이스(위에서 언급했던 ApplicationContext, BeanFactory 등)에 메서드가 존재하는 것이다.

 

ApplicationContext는 BeanFactory를 상속하고 있으며 둘의 차이점은 객체를 생성하는 즉시 인스턴스를 생성하는지 아닌지의 차이다. 무슨 말이냐면 ApplicationContext를 구현한 클래스의 객체는 Pre-loading 방식으로 즉 객체를 new로 생성하는 즉시 Bean 객체를 생성하지만 BeanFactory를 구현한 클래스의 객체는 Lazy-loading 방식으로 즉 getBean 메서드로 요구되기 전까지는 Bean 객체를 생성하지 않는다고 한다. 대부분 웹 애플리케이션에서는 ApplicationContext를 사용한다고 하는데 이에 대해서는 좀 더 알아봐야 할 것 같다.

 

이런 인터페이스의 최상위 인터페이스는 BeanFactory다. 이는 Bean 객체들을 담는 컨테이너의 가장 기본적인 원형으로 이 인터페이스를 구현한 클래스는 여러 Bean 객체를 정의하는 코드를 포함하는 클래스다(이전 포스트의 AppContext 클래스). 각각의 Bean 객체는 메서드 이름으로 구분되는데 이전에 "greeter" 같은 메서드 이름을 사용했던 것이 각각의 Bean 객체를 정의하는 과정의 일환이었던 것이다. 이 BeanFactory에서 Bean을 어떻게 반환(싱글턴 패턴, 프로토타입 패턴 등)할지는 이 인터페이스를 구현한 클래스에서 결정된다.

 

이런 BeanFactory의 목적은 애플리케이션 컴포넌트의 중앙 레지스트리를 구축하고 환경 설정을 중앙화하기 위함이다(a central registry of application components, and centralizes configuration of application components). 객체들이 일일히 설정 파일을 읽을 필요 없이 중앙에서 제공하기 위해서라고 하며 대개 XML 설정 파일이나 어떤 파일에서든(제약이 없다) 설정 값을 읽어서 Bean 객체로 생성한다. 위에서 언급한 AnnotationConfigApplicationContext 등이 그 예일 것이다.

 

스프링에서는 Dependency Injection을 통해 애플리케이션 객체들을 설정하는 것이 좋다고 한다. 이건 무슨 뜻일까? 이는 DI를 좀 더 공부해보고 나서 적어보도록 하겠다.

 

 

[참고 | zetcode.com/springboot/applicationcontext/]

[참고 | wonwoo.ml/index.php/post/1571]

[참고 | docs.spring.io/spring-framework/docs/5.2.8.RELEASE/javadoc-api/org/springframework/beans/factory/BeanFactory.html]