토비의 스프링 정리 프로젝트 #1.5 스프링의 IoC (애플리케이션 컨텍스트, 빈 팩토리, 설정 정보, @Configuration, @Bean)

Jake Seo·2021년 7월 7일
0

토비의 스프링

목록 보기
6/29

스프링의 IoC

스프링의 핵심을 담당하는 것은 빈 팩토리 혹은 애플리케이션 컨텍스트라고 불리는 것이다. 이 두 가지는 이전에 만들어본 DaoFactory를 조금 더 일반화한 것이라고 설명할 수 있다.

오브젝트 팩토리를 이용한 스프링 IoC

애플리케이션 컨텍스트와 설정정보

스프링에서는 스프링이 제어권을 가지고 직접 만들고 관계를 부여하는 오브젝트를 빈(bean) 이라고 부른다. 자바빈, 엔터프라이즈 자바빈에서 말하는 것과 비슷한 오브젝트 단위의 애플리케이션 컴포넌트를 말한다.

스프링 빈은 스프링 컨테이너가 생성, 관계설정, 사용 등을 제어해주는 제어의 역전이 적용된 오브젝트를 가리킨다.

스프링에서 빈의 생성과 관계설정 같은 제어를 담당하는 IoC 오브젝트를 빈 팩토리(Bean Factory)라고 부른다. 빈 팩토리를 조금 더 확장하면 애플리케이션 컨텍스트(Application Context) 가 되며 IoC 방식을 따라 만들어진 일종의 빈 팩토리라고 생각하면 편하다.

앞으로 다룰 내용에서 빈 팩토리애플리케이션 컨텍스트는 동일하다고 봐도 무방하다. 빈 팩토리는 빈을 생성하고 관계를 설정하는 IoC의 기본 기능에 초점을 맞추는 것이고, 애플리케이션 컨텍스트는 애플리케이션 전반에 걸쳐 모든 구성요소의 제어 작업을 담당하는 IoC 엔진이라는 의미가 좀 더 부각된다.

애플리케이션 컨텍스트는 별도의 설정 정보를 참고해서 빈의 생성, 관계설정 등의 제어 작업을 총괄한다. 설정 정보를 담고 있는 무엇인가를 가져와 이를 활용하는 범용적인 IoC 엔진같은 것으로 보면 된다.

이전에 DaoFactory가 했던 설계도 역할을 하는 것이 애플리케이션 컨텍스트설정정보들이라고 보면 된다.

그 자체로 애플리케이션 로직을 담당하지는 않지만, IoC 방식을 이용해 애플리케이션 컴포넌트를 생성하고 관계를 맺어주는 등의 책임을 담당한다.

코드 작성 전 의존성 추가하기

앞으로 스프링 프레임워크의 코드를 작성해야 하는데, 그 전에 의존성을 몇가지 추가해주어야 한다. 나는 Gradle로 실습하여, Gradle 기준으로 작성하겠다.

plugins {
    id 'java'
}

group 'org.example'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
    implementation group: 'org.postgresql', name: 'postgresql', version: '42.2.22'
    implementation group: 'org.springframework', name: 'spring-core', version: '5.3.8'
    implementation group: 'org.springframework', name: 'spring-context', version: '5.3.8'
    implementation group: 'commons-logging', name: 'commons-logging', version: '1.2'
}

test {
    useJUnitPlatform()
}
  • org.springfraemworkspring-core, spring-context
  • commons-loggingcommons-logging

DaoFactory를 사용하는 애플리케이션 컨텍스트

DaoFactory를 스프링의 빈 팩토리가 사용할 수 있는 설정정보로 만들어보자.

  • @Configuration이라는 애노테이션을 클래스에 붙이면, 해당 클래스가 빈 팩토리를 위한 오브젝트 설정을 담당하는 클래스라고 알릴 수 있다.
  • @Bean이라는 애노테이션을 객체 생성 메소드에 붙이면, 해당 메소드가 생성한 객체를 스프링 빈으로서 활용할 수 있다.

이 두 가지 애노테이션만으로 작성한 클래스를 스프링 프레임워크의 빈 팩토리 혹은 애플리케이션 컨텍스트가 IoC 방식의 기능을 제공할 때 사용할 설정정보로 만들 수 있다.

@Configuration // `애플리케이션 컨텍스트` 혹은 `빈 팩토리`가 사용할 설정 정보라는 표시이다.
public class DaoFactory {

    @Bean // 오브젝트 생성을 담당하는 IoC용 메소드라는 표시이다.
    public UserDao userDao() {
        return new UserDao(getConnectionMaker());
    }

    @Bean // 오브젝트 생성을 담당하는 IoC용 메소드라는 표시이다.
    public DSimpleConnectionMaker getConnectionMaker() {
        return new DSimpleConnectionMaker();
    }
}

애플리케이션 컨텍스트를 이용하도록 UserDaoTest 변경해보기

public class UserDaoTest {
    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        ApplicationContext applicationContext
                = new AnnotationConfigApplicationContext(DaoFactory.class);

        UserDao userDao = applicationContext.getBean("userDao", UserDao.class);
        // 아래 주석처리된 방법과 같이 작성해도 무관하다.
        // UserDao userDao = applicationContext.getBean(UserDao.class); 

        User user = new User();
        user.setId("2");
        user.setName("제이크2");
        user.setPassword("jakejake");

        userDao.add(user);

        System.out.println(user.getId() + " register succeeded");

        User user2 = userDao.get(user.getId());
        System.out.println(user2.getName());
        System.out.println(user2.getPassword());

        System.out.println(user2.getId() + " query succeeded");
    }
}

테스트를 실행했을 때도 정상적으로 실행됨을 볼 수 있다.

여태까지의 진행사항을 정리하면,

  • 애노테이션을 이용한 스프링 IoC 설정 정보 클래스를 작성했다.
  • ApplicationContext 인터페이스에 AnnotationConfigApplicationContext() 구현체를 생성했다.
    • AnnotationConfigApplicationContext()를 구성하는데 필요한 설정 정보는 @Configuration 애노테이션을 적용한 DaoFactory.class에서 가져왔다.
  • UserDao를 생성할 때, 단순히 new 생성자를 이용하지 않고 ApplicationContext에 존재하는 UserDao 타입의 스프링 빈을 가져왔다.

사실 UserDao 타입의 스프링 빈을 가져올 때, applicationContext.getBean(UserDao.class)와 같은 방식으로 작성해도 되지만, 간혹 해당 빈을 생성하는 방식이나 구성을 다르게 하는 경우도 있어서 그러한 경우를 고려해서 직접 빈의 이름까지 작성해주는 방식도 존재하는 것이다.

사실 지금까지는 스프링을 적용하긴 했지만 오히려 앞에서 DaoFactory를 이용해 간단히 처리하던 부분을 여러가지 외부 의존성 설치와 애노테이션 사용으로 조금 더 복잡하게만 만든 꼴이다.

뒤에서는 이렇게 스프링을 사용한 IoC를 이용하면 얻는 이점에 대해 알아보자.

애플리케이션 컨텍스트의 동작 방식

기존 오브젝트 팩토리 방식과 스프링 애플리케이션 컨텍스트의 방식을 비교해보자.

일단, 기존 오브젝트 팩토리에 대응되는 것이 스프링의 애플리케이션 컨텍스트이다. IoC 컨테이너, 스프링 컨테이너, 빈 팩토리 모두 크게 보았을 때는 애플리케이션 컨텍스트의 동의어다. 애플리케이션 컨텍스트BeanFactory를 상속하여 확장시킨 것이다.

DaoFactoryDAO 오브젝트를 생성하고, DAOConnectionMaker 구현체 간의 관계를 맺어주는 제한적인 역할을 했다. 반면, 애플리케이션 컨텍스트는 애플리케이션에서 IoC를 적용해 관리할 모든 오브젝트에 대한 생성과 관계 설정을 담당한다.

단, 애플리케이션 컨텍스트는 직접적인 관계 작성 코드는 없고, 생성정보와 연관관계 정보는 별도의 설정정보를 통해서만 얻는다. 때로는 외부 오브젝트 팩토리에 그 작업을 위임하고 그 결과를 가져다가 사용하기도 한다.

  • @Configuration 애노테이션이 붙은 클래스는 스프링 프레임워크(IoC)의 설정정보를 제공한다.
  • @Bean 애노테이션이 붙은 생성 메소드는 스프링 프레임워크에 스프링 빈을 제공한다.

이렇게 애플리케이션 컨텍스트를 이용하면 얻는 이점은 다음과 같다.

애플리케이션 컨텍스트의 이점

클라이언트는 구체적인 팩토리 클래스를 알 필요가 없다.

DaoFactory는 매번 필요할 때마다 팩토리 오브젝트를 생성해야 하는 번거로움이 있다. 애플리케이션 컨텍스트를 이용하면 일관된 방식으로 원하는 오브젝트를 가져올 수 있다. 물론 팩토리 오브젝트를 생성할 필요도 없다.

애플리케이션 컨텍스트는 종합 IoC 서비스를 제공해준다.

애플리케이션 컨텍스트의 역할은 단지 오브젝트 생성과 다른 오브젝트와의 관계 설정이 전부가 아니라, 오브젝트가 만들어지는 방식을 설정하는 방법, 시점과 전략을 다르게 가져가는 방법, 자동생성, 오브젝트 후처리, 정보의 조합, 설정방식 다변화, 인터셉팅 등 오브젝트를 효과적으로 사용할 수 있는 다양한 기능을 제공한다.

스프링 빈이 사용할 수 있는 기반 기술 서비스나 외부 시스템과 연동 등을 컨테이너 차원에서 제공해주기도 한다.

애플리케이션 컨텍스트는 빈을 검색하는 다양한 방법을 제공해준다.

빈 이름으로 검색, 타입으로 검색, 특정 애노테이션 설정된 빈 등 다양한 방식으로 찾을 수 있다.

스프링 IoC 용어 정리

빈 (Bean, 스프링 빈)

스프링이 IoC 방식으로 관리하여 직접 그 생성과 제어를 담당하는 오브젝트를 말한다.

빈 팩토리 (Bean Factory)

스프링 IoC를 담당하는 핵심 컨테이너를 말한다. 빈 등록, 생성, 조회, 반환 등 기타 부가적인 빈 관리 기능을 담당한다. 보통은 빈 팩토리를 바로 사용하기보다 이를 확장한 애플리케이션 컨텍스트를 사용한다. BeanFactory에는 getBean()과 같은 메소드가 정의되어 있다.

애플리케이션 컨텍스트 (Application Context)

빈 팩토리를 확장한 IoC 컨테이너이다. 빈 팩토리의 기능에 추가적으로 스프링이 제공하는 애플리케이션 지원 기능이 포함된다. 스프링에서는 애플리케이션 컨텍스트라는 용어를 빈 팩토리보다 더 많이 사용한다. ApplicationContext애플리케이션 컨텍스트가 구현하는 기본 인터페이스를 가리킨다.

빈 팩토리는 빈의 생성과 제어 관점에서 쓰는 용어이고, 애플리케이션 컨텍스트는 스프링이 제공하는 애플리케이션 지원 기능을 모두 포함해서 이야기하는 용어이다.

설정정보/설정 메타정보 (Configuration Metadata)

애플리케이션 컨텍스트 혹은 빈 팩토리가 IoC를 적용하기 위해 사용하는 메타정보를 말한다. 보통 IoC에 의해 관리될 애플리케이션 오브젝트를 생성하고 구성할 때 사용된다. 애플리케이션의 청사진이라고도 한다.

컨테이너 (Container) 혹은 IoC 컨테이너

애플리케이션 컨텍스트, 빈 팩토리와 같은 의미이다. 컨테이너를 그냥 스프링이라고 부르는 사람도 있다.

스프링 프레임워크

애플리케이션 컨텍스트, 빈 팩토리, IoC 컨테이너를 포함해 스프링이 포함하는 모든 기능을 통틀어 말할 때 사용한다. 그냥 스프링이라고 말하기도 한다.

profile
풀스택 웹개발자로 일하고 있는 Jake Seo입니다. 주로 Jake Seo라는 닉네임을 많이 씁니다. 프론트엔드: Javascript, React 백엔드: Spring Framework에 관심이 있습니다.

0개의 댓글