본문 바로가기

Spring 프레임워크/이론

Spring의 @Configuration, @Bean

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

 

먼저 스프링을 설치하고 예제로 작성했던 코드 중 일부는 다음과 같다.

package basic;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppContext {
    @Bean
    public Greeter greeter(){
        Greeter g = new Greeter();
        g.setFormat("%s, Hello!");
        return g;
    }
}

이 AppContext 클래스는 추후 Main 클래스에서 사용한다. 그 전에 AppContext 클래스에 붙어있는 @Configuration 어노테이션과 내부의 greeter 메서드에 붙어있는 @Bean 어노테이션을 눈여겨 볼 필요가 있다. 이 @Configuration 어노테이션은 이 AppContext 클래스가 스프링의 환경설정을 담당하는 클래스라는 것을 명시하는 것이다.

 

이전에는 수많은 XML 파일을 이용해서 스프링의 환경설정을 수행했지만 요즘, 특히 스프링 부트에서는 대부분 자바 소스 코드를 이용하여 환경설정을 진행한다고 한다. 그래서 이렇게 작성한 환경설정 클래스는 나중에 스프링이 제공하는 클래스(AnnotationConfigApplicationContext 등)에서 읽어서 사용할 수 있다.

 

위의 환경설정 클래스 내부에서는 @Bean이라는 어노테이션이 붙은 메서드가 있다. 스프링은 스프링이 생성하는 객체를 빈(Bean)이라고 부르는데 메서드에 이 어노테이션이 붙었다는 것은 이 메서드(greeter)가 생성하는 객체를 빈(Bean) 객체로 등록하여 스프링이 관리하겠다는 것이다. 메서드의 이름은 나중에 이 빈 객체를 불러올 때 식별자로 사용된다.

 

스프링에서 관리하는 객체의 특징 중 하나는 이 환경설정 클래스에서 생성하는 객체(@Bean)는 싱글턴 패턴으로 작성된다는 것이다. 즉 두 개 이상의 객체가 생성되지 않는다는 것인데 이를 보이기 위해 다음과 같은 코드를 실행해볼 수 있다.

public class Main {
    public static void main(String[] args){
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppContext.class);
        Greeter g1 = ctx.getBean("greeter", Greeter.class);
        Greeter g2 = ctx.getBean("greeter", Greeter.class);

        String msg1 = g1.greet("Spring");
        g1.setFormat("%s, bye!");
        String msg2 = g2.greet("Spring");

        System.out.println(msg1);
        System.out.println(msg2);
        System.out.println(String.format("%s: %s", "Is g1 and g2 same?", g1 == g2));
        ctx.close();
    }
}

현재 Main 클래스에서 사용하는 Greeter 클래스에는 setFormat, greet 메서드로 객체에 이런저런 조작을 수행할 수 있다. 먼저 위에서 작성한 AppContext 클래스를 AnnotationConfigApplicationContext 클래스로 불러온 후 getBean 메서드를 이용해 @Bean 객체를 생성하고 있는데 매개변수로 아까 AppContext 클래스에서 @Bean 어노테이션이 붙은 메서드의 이름을 넘긴다. 이 이름으로 메서드를 참조하여 빈(Bean) 객체를 생성하는 것이다. 이때 메서드의 반환 자료형과 getBean 메서드의 반환값을 저장할 변수의 자료형은 동일해야 한다.

 

위의 AppContext 클래스의 greeter 메서드에서는 Greeter 객체를 매번 생성해서 반환하는 코드를 수행하고 있다. 그러나 g1 객체에 대하여 새로운 포맷을 설정(setFormat)해주고 g2 객체의 메소드를 실행시켜보았더니 변경사항이 반영된 것을 볼 수 있었다. 즉 getBean 메서드로 생성된 두 g1, g2 객체는 동일한 싱글턴 패턴의 객체인 것이다.

 

 

[참고 | zgundam.tistory.com/26]

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

[참고 | www.aladin.co.kr/shop/wproduct.aspx?ItemId=157472828]