1.12.2 AnnotationConfigApplicationContext를 사용한 스프링 컨테이너 인스턴스화 by sh

1.12.2. AnnotationConfigApplicationContext를 사용한 스프링 컨테이너 인스턴스화

다음 섹션에서는 스프링 3.0에서 도입된 스프링의 AnnotationConfigApplicationContext에 대해 설명합니다. 이 다재 다능한 ApplicationContext구현은 입력으로 @Configuration 클래스 뿐만 아니라, 일반 @Component 클래스 및 JSR-330 메타데이터로 어노테이팅된 클래스도 허용할 수 있습니다.

AnnotationConfigApplicationContext

  • BeanFactory의 종류 중 하나. @Configuration 어노테이션을 이용한 자바 코드를 설정 정보로 사용하려면 AnnotationConfigApplicationContext를 이용한다. (즉, Configuration 어노테이션이 붙은 클래스를 설정 정보로 사용함)

    • BeanFactory : 스프링에서 빈의 생성과 빈들의 관계 설정 같은 제어를 담당하는 IoC 오브젝트.

    • ApplicationContext : IoC 방식을 따라 만들어진 일종의 BeanFactory (의 확장).

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

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

간단한 구성

ClassPathXmlApplicationContext를 인스턴스화할 때 스프링 XML 파일을 입력으로 사용하는 것과 같은 방법으로, AnnotationConfigApplicationContext를 인스턴스 화할 때 @Configuration 클래스를 입력으로 사용할 수 있습니다. 이렇게 하면 다음 예제와 같이 스프링 컨테이너를 완전히 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 annotated 클래스가 생성자에 대한 입력으로 제공될 수 있습니다:

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와 같은 스프링 종속성 삽입 어노테이션을 사용한다고 가정합니다

Register(Class<?>…)를 사용하여 프로그래밍 방식으로 컨테이너 빌드하기

인수가 없는 생성자를 사용하여 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();
}

Scan(String…)으로 컴포넌트 검색 활성화

컴포넌트 검색을 사용하려면, 다음과 같이 @Configuration 클래스에 어노테이션을 추가할 수 있습니다:

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

이 어노테이션이 컴포넌트 스캔을 가능하게 해줍니다.

별도로 @Bean 설정을 하지 않고 @ComponentScan을 통해서 Type-safe한 방법으로 설정할 수 있다.

숙련된 스프링 사용자는 스프링의 context:와 동일한 XML 선언에 익숙할 수 있습니다. 네임 스페이스는 다음 예제와 같습니다.

앞의 예에서, com.acme패키지는 @Component-annotated 클래스를 찾기 위해 스캔 되며, 이 클래스는 컨테이너 내에 스프링 빈 정의로 등록됩니다. AnnotationConfigApplicationContext는 다음 예제와 같이 동일한 구성 요소 검색 기능을 허용하는 scan(String…​) 메소드를 제공합니다:

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

@Configuration 클래스는 @Component로 메타 어노테이션이 붙은 클래스 이므로, 이 클래스들은 컴포넌트 스캔의 후보가된다는 점을 기억하십시오. 앞의 예에서, AppConfigcom.acme 패키지 (또는 아래에 있는 패키지) 내에서 선언되었다고 가정하면, scan()을 호출하는 동안 AppConfig가 선택됩니다. 그리고 클래스의 모든 @Bean메소드들을 refresh()할 때 컨테이너 내 빈 정의로 처리되고 등록될 것입니다.

AnnotationConfigWebApplicationContext를 사용한 웹 응용 프로그램 지원

AnnotationConfigApplicationContextWebApplicationContext변형은 AnnotationConfigWebApplicationContext로 사용할 수 있습니다. 스프링 ContextLoaderListener서블릿 리스너, 스프링 MVC DispatcherServlet등을 설정할 때 이 구현체를 사용할 수 있습니다. 다음은 전형적인 스프링 MVC 웹 어플리케이션을 설정하는 web.xml의 예제입니다. (contextClasscontext-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>

Last updated