웹사이트 검색

스프링 @Configuration 주석


Spring @Bean 정의 메소드. 따라서 Spring 컨테이너는 클래스를 처리하고 애플리케이션에서 사용할 Spring Bean을 생성할 수 있습니다.

스프링 @구성

스프링 의존성 주입. Spring Configuration 클래스를 생성하는 방법을 알아봅시다. 간단한 자바 빈 클래스를 만들어 봅시다.

package com.journaldev.spring;

public class MyBean {

	public MyBean() {
		System.out.println("MyBean instance created");
	}
	
}

Spring 프레임워크 클래스를 사용하기 전에 Maven 프로젝트에 종속성을 추가해야 합니다.

<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
		<version>5.0.6.RELEASE</version>
</dependency>

이제 Spring Configuration 클래스를 생성해 보겠습니다.

package com.journaldev.spring;

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

@Configuration
public class MyConfiguration {

    @Bean
    public MyBean myBean() {
		return new MyBean();
	}
	
}

간단한 클래스를 작성하고 간단한 Spring 구성 클래스를 구성해 보겠습니다.

package com.journaldev.spring;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MySpringApp {

	public static void main(String[] args) {
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
		ctx.register(MyConfiguration.class);
		ctx.refresh();

		// MyBean mb1 = ctx.getBean(MyBean.class);

		// MyBean mb2 = ctx.getBean(MyBean.class);

		ctx.close();
	}

}

위의 응용 프로그램을 실행하면 다음과 같은 출력이 생성됩니다.

May 23, 2018 12:34:54 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@ff5b51f: startup date [Wed May 23 12:34:54 IST 2018]; root of context hierarchy
MyBean instance created
May 23, 2018 12:34:54 PM org.springframework.context.support.AbstractApplicationContext doClose
INFO: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@ff5b51f: startup date [Wed May 23 12:34:54 IST 2018]; root of context hierarchy

Spring은 우리가 요청하기도 전에 Bean을 컨텍스트로 로드합니다. 이는 모든 bean이 올바르게 구성되고 문제가 발생할 경우 애플리케이션이 빠르게 실패하도록 하기 위한 것입니다. 또한 ctx.refresh()를 호출해야 합니다. 그렇지 않으면 컨텍스트에서 빈을 가져오려고 할 때 다음과 같은 오류가 발생합니다.

Exception in thread "main" java.lang.IllegalStateException: org.springframework.context.annotation.AnnotationConfigApplicationContext@f0f2775 has not been refreshed yet
	at org.springframework.context.support.AbstractApplicationContext.assertBeanFactoryActive(AbstractApplicationContext.java:1076)
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1106)
	at com.journaldev.spring.MySpringApp.main(MySpringApp.java:11)

MyBean 인스턴스를 가져오는 명령문의 주석을 제거하면 MyBean의 생성자를 호출하지 않는다는 것을 알 수 있습니다. Spring Bean의 기본 범위가 Singleton이기 때문입니다. @Scope 주석을 사용하여 변경할 수 있습니다.

@Configuration 어노테이션을 제거하면 어떻게 될까요?

MyConfiguration 클래스에서 @Configuration 주석을 제거하면 어떻게 됩니까? 여전히 예상대로 작동하고 스프링 빈이 싱글톤 클래스로 등록되고 검색되는 것을 알 수 있습니다. 그러나 이 경우 myBean() 메서드를 호출하면 일반 Java 메서드 호출이 되고 MyBean의 새 인스턴스를 얻게 되며 싱글톤으로 유지되지 않습니다. 이 점을 증명하기 위해 MyBean 인스턴스를 사용할 다른 빈을 정의해 봅시다.

package com.journaldev.spring;

public class MyBeanConsumer {

	public MyBeanConsumer(MyBean myBean) {
		System.out.println("MyBeanConsumer created");
		System.out.println("myBean hashcode = "+myBean.hashCode());
	}

}

업데이트된 Spring Configuration 클래스는 다음과 같습니다.

package com.journaldev.spring;

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

//@Configuration
public class MyConfiguration {

	@Bean
    public MyBean myBean() {
		return new MyBean();
	}
	
	@Bean
    public MyBeanConsumer myBeanConsumer() {
		return new MyBeanConsumer(myBean());
	}
}

이제 MySpringApp 클래스를 실행하면 다음 출력이 생성됩니다.

MyBean instance created
MyBean instance created
MyBeanConsumer created
myBean hashcode = 1647766367

따라서 MyBean은 더 이상 싱글톤이 아닙니다. 이제 @Configuration 주석으로 MyConfiguration에 주석을 다시 달고 MySpringApp 클래스를 실행해 보겠습니다. 이 시간 출력은 아래와 같습니다.

MyBean instance created
MyBeanConsumer created
myBean hashcode = 1095088856

따라서 구성 클래스와 함께 @Configuration 주석을 사용하여 스프링 컨테이너가 원하는 방식으로 작동하는지 확인하는 것이 좋습니다. @Autowired 주석을 사용하지 않으려는 경우. 아래 코드와 같은 것도 작동합니다.

package com.journaldev.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//@Configuration
public class MyConfiguration {

	@Autowired
	MyBean myBean;
	
	@Bean
    public MyBean myBean() {
		return new MyBean();
	}
	
	@Bean
    public MyBeanConsumer myBeanConsumer() {
		return new MyBeanConsumer(myBean);
	}
}

여기까지가 Spring 구성 주석의 전부입니다. 향후 게시물에서 다른 스프링 주석을 살펴보겠습니다.

GitHub 리포지토리에서 예제 코드를 다운로드할 수 있습니다.