Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.
RetroTech 팟캐스트 44BITS 팟캐스트

[Spring 레퍼런스] 2장 Spring 3.0의 새로운 기능과 개선된 점

이 포스팅은 다음의 스프링소스 라이센스를 따릅니다.

이 문서는 개인적인 목적이나 배포하기 위해서 복사할 수 있다. 출력물이든 디지털 문서든 각 복사본에 어떤 비용도 청구할 수 없고 모든 복사본에는 이 카피라이트 문구가 있어야 한다.




2. Spring 3.0의 새로운 기능과 개선된 점

스프링 프레임워크를 사용해 본 적이 있다면 스프링이 2개의 메이저 리비전을 지나왔다는 것을 알고 있을 것이다. 스프링 2.0은 2006년 10월에 릴리즈했고 스프링 2.5는 2007년 11월에 릴리즈했다. 이제 스프링 3.0으로 세 번째 개선을 하였다.

Java SE와 Java EE 지원

스프링 프레임워크는 이제 Java 5 기반이고 Java 6 완전히 지원한다.

게다가 스프링은 J2EE 1.4와 Java EE 5와 호환성이 있으며 동시에 Java EE 6를 일찍부터 지원한다.


2.1 Java 5

제너릭(generic)이나 가변인자(varargs), 그 외 언어적 개선사항 같은 Java 5 기능의 이점을 취하도록 전체 프레임워크 코드를 수정했다. 코드의 하위호환성을 계속 유지하도록 최선을 다했다. 제너릭 컬렉션과 맵의 일관된 사용, 제너릭 팩토리빈(FactoryBean)의 일관된 사용, 스프링 AOP API에서 브릿지 메서드의 일관된 해결책을 제공한다. 제너릭 어플리케이션리스너 (ApplicationListener)는 자동으로 특정이벤트의 타입만 받는다. TransactionCallback과 HibernateCallback같은 모든 콜백 인터페이스는 이제 제너릭 결과값을 선언한다. 전반적으로 스프링 핵심코드를 Java 5를 기반으로 새로 작성되고 최적화했다.

Java 5의 java.util.concurrent와의 닫힌 통합(close integration)을 위해 스프링의 TaskExecutor 추상화를 수정했다. ExecutorService 어댑터, ThreadFactory 통합 뿐 아니라 이제 Callable과 Future를 지원하는 퍼스트 클래스를 제공한다. 이는 가능한 한 JSR-236(Java EE 6을 위한 동시성 유틸리티)과 맞추었다. 게다가 새로운 @Async 어노테이션(또는 EJB 3.1의 @Asynchronous 어노테이션)으로 비동기 메서드 호출을 지원한다.


2.2 개선된 문서

스프링 레퍼런스 문서도 스프링 3.0의 수정사항과 새로운 기능을 반영해서 상당히 수정되었다. 이 문서에 오류가 없도록 노력하였음에도 약간의 에러가 있을 수 있다. 오타나 심각한 오류를 발견한다면 약간의 시간을 할애해서 이슈를 올려 스프링 팀에게 알려주기를 부탁한다.


2.3 새로운 글과 튜토리얼

스프링 3의 기능에 대한 좋은 글과 튜토리얼을 스프링 문서에서 볼 수 있다.

예제들은 스프링 3의 새로운 기능들에 맞춰서 개선되고 수정되었다. 추가로 예제 소스는 전용 SVN 저장소로 이동했다. 다음 링크에서 소스를 볼 수 있다.

https://anonsvn.springframework.org/svn/spring-samples/

그래서 예제들은 더는 스프링 3과 함께 배포지 않는다. 위의 저장소에서 따로 다운받아야 한다. 하지만 이 문서는 다양한 기능을 설명하기 위해 몇몇 예제들(특히 Petclinic)을 참조할 것이다.

Note
서브버전(SVN)에 대한 더 자세한 정보는 프로젝트 홈페이지를 참고해라. http://subversion.apache.org/


2.4 새로운 모듈 구조와 빌드 시스템

프레임워크 모듈을 수정했고 이제부터는 모듈 jar마다 하나의 소스트리로 분리해서 관리한다.

  • org.springframework.aop
  • org.springframework.beans
  • org.springframework.context
  • org.springframework.context.support
  • org.springframework.expression
  • org.springframework.instrument
  • org.springframework.jdbc
  • org.springframework.jms
  • org.springframework.orm
  • org.springframework.oxm
  • org.springframework.test
  • org.springframework.transaction
  • org.springframework.web
  • org.springframework.web.portlet
  • org.springframework.web.servlet
  • org.springframework.web.struts
스프링 웹 플로우(Web Flow) 2.0을 새로운 빌드시스템으로 사용한다. 웹 플로우는 다음과 같은 특징이 있다.

  • Ivy기반의 "Spring Build" 시스템
  • 일관된 배포과정
  • 일관된 의존성 관리
  • 일관된 OSGi manifest 생성
Note:
전체 프레임워크를 대부분 포함하고 있는 spring.jar artifact는 더는 제공하지 않는다.


2.5 새로운 기능

다음은 스프링 3.0의 새로운 기능들이다. 이번 장 후반부에서 각 기능의 세부사항을 살펴볼 것이다.

  • 스프링 표현언어(Expression Language)
  • IoC 개선/자바 기반의 빈(bean) 메타데이터
  • 범용적인 타입 컨버전 시스템과 필드 포매팅 시스템
  • 스프링 웹 서비스 프로젝트의 객체와 XML을 매핑하는 기능(OXM) 추가
  • 광범위한 REST 지원
  • @MVC 추가
  • 선언적인 모델 유효성 확인
  • Java EE 6에 대한 조기 지원
  • 데이터베이스 지원 내장

2.5.1 자바 5로 코어 API 개선

BeanFactory 인터페이스는 가능한 한 타입있는 빈(bean) 인스턴스를 돌려준다.

  • T getBean(Class<T> requiredType)
  • T getBean(String name, Class<T> requiredType)
  • Map<String, T> getBeansOfType(Class<T> type)
Spring의 TaskExecutor 인터페이스는 이제 java.util.concurrent.Executor를 상속받는다.

  • 상속받은 AsyncTaskExecutor는 표준 Callable와 Future를 지원한다.
자바 5기반의 새로운 변환 API와 SPI

  • 무상태 ConversionService와 Converters
  • 표준 JDK 프로퍼티 에디터는 필요 없어졌다.
타입이 있는 ApplicationListener<E>


2.5.2 스프링 표현 언어(Expression Language)

스프링은 표현언어를 도입했다. 스프링의 표현언어는 일반적인 EL과 문법상으로는 유사하지만 훨 더 많은 기능을 제공한다. 표현언어는 XML이나 빈설정에 기반을 둔 어노테이션을 정의할 때 사용할 수 있다. 또한, 스프링 표현언어는 스프링의 모든 제품에 걸 표현언어 지원의 근간이 된다. 새로운 기능의 세부사항은 스프링 표현언어 (SpEL). 챕터에서 설명한다.

스프링 커뮤니티에 단독으로 제공하기 위해 스프링 표현언어를 만들었고 스프링의 모든 제품군에서 사용할 수 있는 표현언어를 지원하려는 목적이었다. 스프링 제품군의 프로젝트에서 나온 요구사항으로 기반으로 기능을 만들었다. SpringSource Tool Suite 에 기반을 둔 이클립스에서 코드 자동완성에 대한 요구사항도 포함한다.

다음은 데이터베이스 설정의 프로퍼티 설정에서 표현언어를 어떻게 사용하는지를 보여주는 예제이다.


<bean class="mycompany.RewardsTestDatabase">
    <property name="databaseName"
        value="#{systemProperties.databaseName}"/>
    <property name="keyGenerator"
        value="#{strategyBean.databaseKeyGenerator}"/>
</bean>

이 기능은 어노테이션으로 컴포넌트를 설정할 때도 사용할 수 있다.


@Repository 
public class RewardsTestDatabase {

    @Value("#{systemProperties.databaseName}")
    public void setDatabaseName(String dbName) { … }

    @Value("#{strategyBean.databaseKeyGenerator}")
    public void setKeyGenerator(KeyGenerator kg) { … }
}


2.5.3 제어의 역전 (IoC) 컨테이너

2.5.3.1 자바기반의 빈(bean) 메타데이터

JavaConfig 프로젝트의 몇몇 핵심 기능을 스프링 프레임워크에 추가했다. 이 말은 다음 어노테이션을 이제 직접 지원한다는 의미이다.

  • @Configuration
  • @Bean
  • @DependsOn
  • @Primary
  • @Lazy
  • @Import
  • @ImportResource
  • @Value
다음은 새로운 JavaConfig 기능을 사용해서 기본적인 설정을 제공하는 자바 클래스의 예제다.


package org.example.config;

@Configuration
public class AppConfig {
    private @Value("#{jdbcProperties.url}") String jdbcUrl;
    private @Value("#{jdbcProperties.username}") String username;
    private @Value("#{jdbcProperties.password}") String password;

    @Bean
    public FooService fooService() {
        return new FooServiceImpl(fooRepository());
    }

    @Bean
    public FooRepository fooRepository() {
        return new HibernateFooRepository(sessionFactory());
    }

    @Bean
    public SessionFactory sessionFactory() {
        // session factory 연결
        AnnotationSessionFactoryBean asFactoryBean = 
            new AnnotationSessionFactoryBean();
        asFactoryBean.setDataSource(dataSource());
        // 추가적인 설정
        return asFactoryBean.getObject();
    }

    @Bean
    public DataSource dataSource() { 
        return new DriverManagerDataSource(jdbcUrl, username, password);
    }
}

이 설정이 동작하게 하려면 어플리케이션 컨텍스트 XML 파일에 다음 컴포넌트 스캔을 추가해야 한다.


<context:component-scan base-package="org.example.config"/>
<util:properties id="jdbcProperties" location="classpath:org/example/config/jdbc.properties"/>

또는 AnnotationConfigApplicationContext를 직접 사용하는 @Configuration 클래스를 사용할 수 있다.


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

AnnotationConfigApplicationContext에 대한 전체 정보는 Section 4.12.2, “AnnotationConfigApplicationContext를 사용하는 스프링 컨테이너 예제 살펴보기”를 봐라.


2.5.3.2 컴포넌트안에서 빈(bean) 메타데이터 정의하기

@Bean 어노테이션을 사용한 메서드는 스프링 컴포넌트안에서도 사용할 수 있다. 이 메서드들은 컨터이너에 팩토리빈을 정의하는데 기여한다. 더 자세한 정보는 컴포넌트안에서 빈(bean) 메타데이터 정의하기를 참고해라.


2.5.4 범용적인 타입 컨버전 시스템과 필드 포매팅 시스템

범용적인 타입 컨버전 시스템을 도입했다. 타입 컨버전을 위해 SpEL로 타입 컨버전 시스템을 사용한다. 빈 프로퍼티 값에 바인딩할 때도 스프링 컨테이너와 DataBinder로 타입 컨버전 시스템을 사용할 수 있다.

추가로 필드값을 포매팅하기 위해 포매터 SPI를 도입하였다. 포매터 SPI는 스프링 MVC 같은 클라이언트 환경에서 사용하는 JavaBean PropertyEditor를 더 간단하고 튼튼하게 대체한다.

2.5.5 데이터 티어

스프링 웹 서비스 프로젝트의 객체와 XML을 매핑하는 기능 (OXM)은 스링 프레임워크의 코어로 이동했다. OXM기능은 org.springframework.oxm 패키지에 있다. OXM 모듈의 사용방법에 대한 더 자세한 내용은 O/X 매를 사용하는 XML 마샬링 챕터에서 설명한다.

2.5.6 웹 티어

웹 티어에서 가장 흥미로운 새 기능은 REST스러운 웹 서비스와 웹 어플리케이션 구축에 대한 지원이다. 어떤 웹 어플리케이션에서도 사용할 수 있는 새로운 어노테이션도 추가했다.

2.5.6.1 광범위한 REST 지원

기존에 존재하는 MVC 웹 프레임워크의 어노테이션을 확장해서 REST스러운 어플리케이션 구축에 대한 서버 측 지원을 추가했다. 클라이언트 측 지원은 JdbcTemplate나 JmsTemplate 같은 템플릿 클래스처럼 RestTemplate 클래스로 제공한다. 서버 측과 클라이언트 측 모두 REST기능은 HTTP 요청과 응답을 나타내는 객체의 변환을 위해 HttpConverter를 사용한다.

MarshallingHttpMessageConverter는 앞에서 이야기했던 개체를 XML로 매하는기능을 사용한다.

더 자세한 내용은 MVC와 RestTemplate을 참고해라.

2.5.6.2 @MVC 추가

스프링 MVC 설정을 엄청나게 간단하게 하는 mvc 네임스페이스를 도입했다.

@CookieValue와 @RequestHeaders같은 어노테이션을 추가했다. 더 자세한 내용은 @CookieValue 어노테이션으로 쿠키값 매핑하기과 @RequestHeader 어노테이션으로 요청 헤더 속성 매핑하기를 봐라.

2.5.7 선언적인 모델 유효성 확인

JSR 303을 포함해서 여러 가지 유효성 확인 지원이 개선되었고 기본 프로바이더로 Hibernate Validator를 사용한다.

2.5.8 Java EE 6에 대한 조기 지원

새로운 @Async 어노테이션(또는 EJB 3.1의 @Asynchronous 어노테이션)을 사용해서 비동기 메서드 호출을 지원한다.

JSR 303, JSF 2.0, JPA 2.0 등등

2.5.9 데이터베이스 지원 내장

HSQL, H2, Derby 같은 내장 자바 데이터베이스 엔진을 편리하게 지원한다.
2012/01/17 02:35 2012/01/17 02:35