JAVA/Spring

[Spring] 스프링 컨테이너 (Spring Container)

4Legs 2021. 4. 1. 21:02

스프링 컨테이너 (Spring Container)

스프링 컨테이너는 스프링 빈들을 생성 및 관리하며, 스프링 빈 간의 의존관계 주입을 대신 해 준다.

스프링 컨테이너는 스프링 코드 내에서 ApplicationContext 인터페이스의 구현체로 표현된다.

//Configuration 클래스로 스프링 컨테이너 생성
ApplicationContext acConfig = new AnnotationConfigApplicationContext(AppConfig.class);

//XML 파일로 스프링 컨테이너 생성
ApplicationContext acXml = new GenericXmlApplicationContext("appconfig.xml");

 

다음 예시 코드를 통해 스프링 컨테이너에서 빈이 등록되고 의존관계가 설정되는 과정을 살펴보자.

@Configuration
public class AppConfig{
    
    @Bean
    public ExampleService exampleService(){
        return new ExampleService(
                                ExampleRepository(), 
                                ExamplePolicy()));
    }

    @Bean
    public ExampleRepository exampleRepository(){
        //ExampleRepository는 인터페이스임
        //DBExampleRepository는 이 인터페이스의 특정 구체 클래스
        return new DBExampleRepository();
    }

    @Bean
    public ExamplePolicy examplePolicy(){
        //마찬가지로 ExamplePolicy는 인터페이스
        return new FixedExamplePolicy();
    }
}

 

우선 AppConfig 클래스를 통해 BeanDefinition을 생성하고, 각 빈들을 스프링 컨테이너에 등록한다.

이 때 등록되는 스프링 빈들은 모두 싱글톤 객체로써 저장된다. 여러 다른 사용자들이 동시에 빈을 조회해도 이들은 모두 같은 객체를 가리키게 된다.

빈 설정 파일을 통해 스프링 컨테이너에 스프링 빈을 등록

기본적으로 빈 이름은 메소드 이름으로 등록된다. 만약 다른 이름을 쓰고 싶다면 다음과 같이 작성한다.

@Bean(name="beanNameExample")

 

위 코드에서 나타나는 의존성은 다음과 같다.

[exampleService → exampleRepository], [exampleService → examplePolicy]

스프링 컨테이너에서의 의존관계 주입

 

스프링 빈 조회

스프링 컨테이너에서 스프링 빈은 다음과 같은 방법들로 조회할 수 있다.

ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

//빈 이름으로 조회
ExampleService exampleService = ac.getBean("exampleService", ExampleService.class);

//빈 타입으로 조회
ExampleRepository exampleRepository = ac.getBean(ExampleRepository.class);

//구체 타입으로 조회 (유연성 낮음)
DBExampleRepository dbExampleRepository = ac.getBean("exampleRepository", DBExampleRepository.class);

 

동일한 타입이 둘 이상 존재하는 경우

스프링 빈을 타입으로 조회 시, 동일 타입의 스프링 빈이 둘 이상 존재하면 오류가 발생한다.

이 경우 빈 이름을 지정해 특정 빈만 조회하도록 하여 오류를 피할 수 있다.

ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

//빈 타입으로 조회
//이 때 ExampleRepository 타입의 빈이 둘 이상이면 오류 발생
//ExampleRepository exampleRepository = ac.getBean(ExampleRepository.class);

//빈 이름을 부여해 하나의 빈만 조회하도록 수정
ExampleRepository exampleRepository = ac.getBean("repository1", ExampleRepository.class);

 

특정 타입의 빈을 모두 조회하기

ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

void findAllBeanByType(){
    Map<String, ExampleRepository> result = ac.getBeansOfType(ExampleRepository.class);
}

ExampleRepository는 인터페이스임에 유의하자.

즉, 위 코드는 스프링 컨테이너에 등록된 ExampleRepository 인터페이스를 구현한 클래스 빈들을 조회한다.

이 때, 상위 클래스 타입으로 조회하면 하위 클래스 타입도 함께 조회된다. 즉, 최상위 클래스인 Object 타입으로 조회하면 모든 스프링 빈을 조회할 수 있다.

 

BeanFactory

BeanFactory는 스프링 컨테이너의 최상위 인터페이스로, 스프링 빈을 관리하고 조회하는 역할을 담당한다.

위 코드에서 사용했던 getBean() 메소드 역시 BeanFactory에서 제공한다.

ApplicationContext 와의 차이

ApplicationContext가 더 하위 인터페이스이기 때문에, ApplicationContext는 BeanFactory의 기능들과 함께 부가적인 여러 기능들을 제공한다.

부가적인 기능으로는 메시지 소스, 환경변수, 이벤트, 리소스 조회 등이 있다.

 

 

Reference

인프런 : 스프링 핵심 원리 - 기본편

'JAVA > Spring' 카테고리의 다른 글

[Spring] 스프링 빈 (Spring Bean)  (0) 2021.04.01
[Spring] 의존성 주입 (DI, Dependency Injection)  (0) 2021.03.10