JAVA/Spring

[Spring] 스프링 빈 (Spring Bean)

4Legs 2021. 4. 1. 02:17

스프링 빈 (Spring Bean)

스프링 컨테이너가 관리하는 자바 객체를 우리는 빈(Bean)이라 한다.

빈은 Spring IOC 컨테이너에 의해 인스턴스화, 관리 및 생성되며, 애플리케이션의 핵심을 이루는 객체이다.

※ IOC : 제어의 역전 (Inversion of Control)

 

빈의 등록

우리는 두 가지 방법으로 빈을 스프링 컨테이너에 등록할 수 있다.

설정 메타 데이터(XML) 사용한 등록

<bean id="beanExample" class="practice.BeanExample"></bean>

XML을 이용한 방법은 컴파일 없이 빈 설정 정보를 변경할 수 있다는 장점이 있다.

XML 설정 파일을 넘기는 데 GenericXmlApplicationContext 를 사용한다.

//appConfig.xml 파일을 통해 스프링 컨테이너에 빈 설정 정보 전달
ApplicationContext ac = new GenericXmlApplicationContext("appConfig.xml");

//스프링 컨테이너에서 빈 하나를 찾는 코드
BeanExample beanExample = ac.getBean("beanExample", BeanExample.class);

 

@Bean 어노테이션 사용한 등록

@Configuration
public class AppConfig {
    //각 컴포넌트들을 스프링 빈에 직접 등록하는 클래스 (설정 정보 XML의 역할을 한다.)
    
    
    @Bean  //이 어노테이션이 붙은 객체는 스프링 컨테이너에 빈으로 등록된다.
    public BeanExample beanExample(){
        return new BeanExample();
    }
}

어노테이션을 사용해, 빈 설정 정보를 자바 코드로 구현하는 방법이다.

이 방법은 설정 정보를 넘기는 데 AnnotationConfigApplicationContext 를 사용한다.

//appConfig.xml 파일을 통해 스프링 컨테이너에 빈 설정 정보 전달
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

//스프링 컨테이너에서 빈 하나를 찾는 코드
BeanExample beanExample = ac.getBean("beanExample", BeanExample.class);

 

BeanDefinition

우리는 빈 설정 정보를 스프링 컨테이너에게 전달하는 데에 있어 위에서 살펴본 두 방법 모두를 사용할 수 있다.

두 방법의 혼용이 가능한 이유는 BeanDefinition이라는 추상화가 존재하기 때문이다.

즉, XML 파일을 읽건, Configuration 클래스를 읽건 결과적으로는 빈 설정 메타 정보인 BeanDefinition을 생성하기 때문에, 어떤 방법을 사용해도 상관없다.

 

스프링 빈의 생명주기 콜백

스프링 빈은 객체를 생성한 후에 의존관계 주입(DI)이 이루어진다.

즉, 의존관계 주입이 다 끝난 후에야 객체 내의 데이터를 사용할 준비가 완료된다. 따라서 초기화 작업들은 의존관계 주입이 모두 끝난 후에 진행되어야 할 것이다.  (이 시점 이전에 데이터를 찾으려 한다면 null을 받을 수도 있다.)

그렇다면 우리는 이 시점을 어떻게 알 수 있을까?

 

스프링 빈의 이벤트 생명주기

스프링 컨테이너 생성 → 스프링 빈 생성 → 의존관계 주입 → 초기화 콜백 → 사용 → 소멸전 콜백 → 스프링 종료

여기서 초기화 콜백은 빈이 생성되고, 빈의 의존관계 주입이 끝난 후 호출되며,

소멸전 콜백은 빈이 소멸되기 직전에 호출된다.

따라서 만약 우리가 의존관계 주입이 끝난 후, 빈을 사용하기 전에 수행해야 할 어떤 작업들이 있다면 초기화 콜백에 구현하면 될 것이다.

 

인터페이스를 이용한 구현 : InitializingBean, DisposableBean

InitializingBean, DisposableBean 인터페이스를 구현하도록 해 각각 초기화, 소멸전 콜백을 구현하는 방법이다.

public class Example implements InitializingBean, DisposableBean{
    //...

    //초기화 콜백 : InitializingBean 인터페이스의 추상 메소드
    @Override
    public void afterPropertiesSet() throws Exception{
        //...
    }

    //소멸전 콜백 : DisposableBean 인터페이스의 추상 메소드
    @Override
    public void destroy() throws Exception{
        //...
    }
}

 

@Bean에 특정 메소드를 지정

@Bean 어노테이션에 초기화 및 소멸전 콜백에 해당하는 메소드를 지정할 수 있다.

@Bean(initMethod="init", destroyMethod="close")

 

어노테이션 사용

메소드에 @PostConstruct, @PreDestroy를 붙여 각각 초기화, 소멸전 콜백 메소드임을 나타낼 수 있다.

//초기화 콜백
@PostConstruct
public void init(){
    //...
}

@PreDestroy
public void close(){
    //...
}

 

 

 

Reference

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