스프링 @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 리포지토리에서 예제 코드를 다운로드할 수 있습니다.