Instantiating the Spring Container by Using `AnnotationConfigApplicationContext`

Dev.Hammy·2024년 3월 16일
1

다음 섹션에서는 Spring 3.0에 도입된 Spring의 nnotationConfigApplicationContext를 문서화합니다. 이 다재다능한 ApplicationContext 구현은 @Configuration 클래스뿐만 아니라 일반 @Component 클래스와 JSR-330 메타데이터로 어노테이션이 달린 클래스도 입력으로 허용할 수 있습니다.

@Configuration 클래스가 입력으로 제공되면 @Configuration 클래스 자체가 Bean 정의로 등록되고 클래스 내에서 선언된 모든 @Bean 메소드도 Bean 정의로 등록됩니다.

@Component 및 JSR-330 클래스가 제공되면 Bean 정의로 등록되며, 필요한 경우 해당 클래스 내에서 @Autowired 또는 @Inject와 같은 DI 메타데이터가 사용된다고 가정합니다.

Simple Construction

ClassPathXmlApplicationContext를 인스턴스화할 때 Spring XML 파일을 입력으로 사용하는 것과 거의 같은 방식으로 AnnotationConfigApplicationContext를 인스턴스화할 때 @Configuration 클래스를 입력으로 사용할 수 있습니다. 이는 다음 예제에서 볼 수 있듯이 Spring 컨테이너를 XML 없이 완전히 사용할 수 있게 해줍니다.

public static void main(String[] args) {
	ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
	MyService myService = ctx.getBean(MyService.class);
	myService.doStuff();
}

앞서 언급했듯이 AnnotationConfigApplicationContext@Configuration 클래스에서만 작동하도록 제한되지 않습니다. 다음 예제와 같이 @Component 또는 JSR-330 어노테이션이 달린 클래스를 생성자에 대한 입력으로 제공할 수 있습니다.

public static void main(String[] args) {
	ApplicationContext ctx = new AnnotationConfigApplicationContext(MyServiceImpl.class, Dependency1.class, Dependency2.class);
	MyService myService = ctx.getBean(MyService.class);
	myService.doStuff();
}

앞의 예제에서는 MyServiceImpl, Dependency1Dependency2@Autowired와 같은 Spring 종속성 주입 주석을 사용한다고 가정합니다.

Building the Container Programmatically by Using register(Class<?>...)

인수가 없는 생성자(no-arg construdtor)를 사용하여 AnnotationConfigApplicationContext를 인스턴스화한 다음, register() 메서드를 사용하여 구성할 수 있습니다. 이 접근 방식은 AnnotationConfigApplicationContext를 프로그래밍 방식으로 구축할 때 특히 유용합니다. 다음 예에서는 그 방법을 보여줍니다.

public static void main(String[] args) {
	AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
	ctx.register(AppConfig.class, OtherConfig.class);
	ctx.register(AdditionalConfig.class);
	ctx.refresh();
	MyService myService = ctx.getBean(MyService.class);
	myService.doStuff();
}

Enabling Component Scanning with scan(String...)

component scanning을 활성화하려면 다음과 같이 @Configuration 클래스에 어노테이션을 추가하면 됩니다.

@Configuration
@ComponentScan(basePackages = "com.acme") // (1)
public class AppConfig  {
	// ...
}

(1) 이 어노테이션을 사용하면 component scanning이 가능해집니다.

[Tip]
숙련된 Spring 사용자는 다음 예제에 표시된 Spring의 context: 네임스페이스와 동등한 XML 선언에 익숙할 수 있습니다.

<beans>
	<context:component-scan base-package="com.acme"/>
</beans>

이전 예제에서는 @Component 어노테이션이 달린 클래스를 찾기 위해 com.acme 패키지를 스캔하고 해당 클래스는 컨테이너 내에 Spring Bean 정의로 등록됩니다. AnnotationConfigApplicationContext는 다음 예제와 같이 동일한 component-scanning 기능을 허용하기 위해 scan(String…​) 메서드를 노출합니다.

public static void main(String[] args) {
	AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
	ctx.scan("com.acme");
	ctx.refresh();
	MyService myService = ctx.getBean(MyService.class);
}

[Note]
@Configuration 클래스는 @Component로 메타 어노테이션을 달았으므로 컴포넌트 검색의 후보라는 점을 기억하세요. 앞의 예에서는 AppConfigcom.acme 패키지(또는 그 아래의 모든 패키지) 내에서 선언되었다고 가정하고 이는 scan() 호출 중에 선택됩니다. refresh() 시 모든 @Bean 메소드가 처리되어 컨테이너 내에서 Bean 정의로 등록됩니다.

Support for Web Applications with AnnotationConfigWebApplicationContext

AnnotationConfigApplicationContextWebApplicationContext 변형은 AnnotationConfigWebApplicationContext와 함께 사용할 수 있습니다. Spring ContextLoaderListener 서블릿 리스너, Spring MVC DispatcherServlet 등을 구성(configure)할 때 이 구현을 사용할 수 있습니다. 다음 web.xml 조각은 일반적인 Spring MVC 웹 애플리케이션을 구성합니다(contextClass context-param 및 init-param 사용에 유의하세요).

<web-app>
	<!-- Configure ContextLoaderListener to use AnnotationConfigWebApplicationContext
		instead of the default XmlWebApplicationContext -->
	<context-param>
		<param-name>contextClass</param-name>
		<param-value>
			org.springframework.web.context.support.AnnotationConfigWebApplicationContext
		</param-value>
	</context-param>

	<!-- Configuration locations must consist of one or more comma- or space-delimited
		fully-qualified @Configuration classes. Fully-qualified packages may also be
		specified for component-scanning -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>com.acme.AppConfig</param-value>
	</context-param>

	<!-- Bootstrap the root application context as usual using ContextLoaderListener -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- Declare a Spring MVC DispatcherServlet as usual -->
	<servlet>
		<servlet-name>dispatcher</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<!-- Configure DispatcherServlet to use AnnotationConfigWebApplicationContext
			instead of the default XmlWebApplicationContext -->
		<init-param>
			<param-name>contextClass</param-name>
			<param-value>
				org.springframework.web.context.support.AnnotationConfigWebApplicationContext
			</param-value>
		</init-param>
		<!-- Again, config locations must consist of one or more comma- or space-delimited
			and fully-qualified @Configuration classes -->
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>com.acme.web.MvcConfig</param-value>
		</init-param>
	</servlet>

	<!-- map all requests for /app/* to the dispatcher servlet -->
	<servlet-mapping>
		<servlet-name>dispatcher</servlet-name>
		<url-pattern>/app/*</url-pattern>
	</servlet-mapping>
</web-app>

[Note]
프로그래밍 방식 사용 사례의 경우 GenericWebApplicationContextAnnotationConfigWebApplicationContext 대신 사용할 수 있습니다. 자세한 내용은 GenericWebApplicationContext javadoc을 참조하세요.

2개의 댓글

comment-user-thumbnail
2024년 3월 20일

아무무무무

1개의 답글