Whiteship's Note

'Spring/etc'에 해당되는 글 26건

  1. 2010.06.04 [스프링 퀴즈] @Autowired (4)
  2. 2009.12.23 스프링 3.0의 설정 간편화
  3. 2009.12.08 스프링의 로깅 의존성 (2)
  4. 2009.10.27 [전자정부 개발프레임워크 교육자료] 표준 프레임워크 개요 PPT 감상문 (6)
  5. 2009.07.27 스프링의 이메일 기능 지원과 테스트를 살펴보자 (2)
  6. 2009.04.20 What's new in Spring 3.0? (2)
  7. 2009.04.03 우와~ 스프링 tc 서버다!! (6)
  8. 2009.03.23 스프링 프레임워크 트레이닝 갈까말까 (6)
  9. 2009.03.09 REST in Spring 3: @MVC (8)
  10. 2009.03.05 STS(Spring Tool Suite) 2.0 RC 버전의 OSGi 개발 툴 (2)
  11. 2009.03.04 스프링 3.0 m2 빌드 삽질 중 (4)
  12. 2009.02.26 Petclinic을 통해 스프링 3.0 주요기능 살펴보기 (6)
  13. 2009.02.07 스프링 트랜잭션 주의할 것 (7)
  14. 2009.02.04 빈 속성에 값 설정 했는지 확인하기
  15. 2009.02.04 싱글톤, 비싱글톤 언제 써야 할까? (9)
  16. 2009.01.21 DI(Dependency Injection)의 장점
  17. 2009.01.16 스프링과 디자인 패턴 (2)
  18. 2009.01.07 그루비 사용자와 스프링 (2)
  19. 2009.01.05 드디어 한국에서도 SpringSource에서 직접 교육을 하네요. (4)
  20. 2008.12.12 뢉 해럽 쌩큐 (2)
  21. 2008.12.12 Spring by Example (2)
  22. 2008.12.08 스프링 프레임워크 3.0 M1 배포~
  23. 2008.12.04 로드 존슨과 친구들이 싸인한 스프링 책이 나에게 주는 의미 (6)
  24. 2008.11.29 스프링 프레임워크 3.0 m1 임박.
  25. 2008.11.21 Toby's J2EE Development without EJB 정리 (4)
  26. 2008.11.18 스프링을 사용하는 애플리케이션의 성능 최적화 방안

[스프링 퀴즈] @Autowired

Spring/etc : 2010.06.04 17:30


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class AutowiredTest {

    @Autowired DataSource dataSource;

    @Test
    public void notNull(){
        assertThat(dataSource, is(notNullValue()));
    }

}

위와 같은 테스트가 있다. 위 코드가 있는 곳과 같은 패키지에 AutowiredTest-context.xml 이라는 빈 설정 파일을 만들었다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean class="org.springframework.jdbc.datasource.SimpleDriverDataSource"/>

</beans>

1. 이렇게 설정했을 때 테스트는 어떻게 될까? 깨질까? 성공할까?

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean class="org.springframework.jdbc.datasource.SimpleDriverDataSource"/>

    <bean class="org.springframework.jdbc.datasource.SimpleDriverDataSource"/>

</beans>

2. 이렇게 설정했다면 어떻게 될까?

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource"/>

    <bean id="testDataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource"/>

</beans>

3. 그럼 이건 어떨까?

셋다 맞춘 분에게 물어보고 싶은 질문이 있는데;; 맞추시는 분께 댓글로 질문 드리겠습니다.
top

  1. Favicon of http://lckymn.com BlogIcon Kevin 2010.06.04 19:41 PERM. MOD/DEL REPLY

    저렇게 해본적이 없어서 확실치는 않지만,
    설정파일이나 설정파일 위치에 문제가 없다는 가정하에
    ("설정파일 위치가 제대로 설정 안돼서 모두 실패" 혹은
    "설정파일의 설정이 잘못돼서 모두 실패" 이런거는 아니라고 가정... ㅡ_ㅡ;
    이거 잘 기억이 안 나거든요. ^^; )
    1. 알아서 타입추론해서 주입돼서 성공
    2. 주입하려는 타입의 instance가 하나 이상 존재해서 테스트 하기 전에 DI하면서 에러
    3. id가 dataSource인 instance가 주입돼서 성공

    SimpleDriverDataSource가 DataSource implementing 하는거 맞죠? :)
    그나저나 혹시 만에 하나 맞더라도 질문은 다음분께 양보하는 미덕을 발휘해 봅니다. :D

    Favicon of http://whiteship.me BlogIcon 기선 2010.06.04 21:13 PERM MOD/DEL

    Kevin님께서 푸시면 어떡합니다~~ㅋㅋ

    원래 드리려고 했던 질문은 왜 id로 먼저 확인안하고 타입으로 먼저 찾아볼까요? 라는 거였는데 집에 오는길에 생각하다가 풀렸습니다.

    id 먼저 확인했다가 그 빈이 원하는 타입이 아니면 또 다시 원하는 타입에 해당하는걸로 찾아봐야 할테니 그냥 애초에 타입으로 먼저 찾는게 id로 먼저 찾아보는 것보다 나은 것 같더라구요.

    Favicon of http://lckymn.com BlogIcon Kevin 2010.06.05 18:38 PERM MOD/DEL

    헉! 제가 풀면 안되는거였나요? @_@; 다음 질문이라도 양보해서 다행... (응?ㅡ_ㅡ?)
    그나저나 맞기는 한건지...ㅡ_ㅡ;
    요즘은 @Configuration 위주로 써서요.
    xml은 security 쪽이랑, db 관련된 쪽만 쓰는데,
    여기서 같은 타입의 객체를 두개이상 만들일이 없어서
    가물가물합니다. :)
    (View도 다 @Configuration 에서 만들어 버립니다. :) )
    아... component scanning 도 xml 쓰는군요.

    @Configuration 에서 같은 타입의 객체를 두개이상
    생성 해야 할경우, 따로 설정하기 보다
    method 이름을 다르게 하고,
    그게 맞게 변수이름을 사용해서 처리하는식으로 써서요.

    Favicon of http://whiteship.me BlogIcon 기선 2010.06.06 22:14 PERM MOD/DEL

    벌써 @Configuration을 애용하고 계시군요.

    얼마전에 트위터인지 버즈에서 링크건 내용 중에 그런게 있더라구요. '사람들은 편한것 보다 익숙한 것을 사용한다.' 였나? 머 그런 비슷한 거였는데.. 그 글을 보면서 공감가는 부분이 많았는데

    @Configruation에 대한 댓글을 보다보니 갑자기 그 글귀가 생각나네요.ㅎ

    사실 저도 같은 타입 빈을 두개씩 등록해서 사용하는 경우는 거의 드물구요. 위 테스트는 @Autoewired 학습 테스트 정도에 해당하겠네요.

    @Autowired가 "타입으로 자동주입" 이라는 생각으로 굳어져있었거든요. 그래서 내심 세번째 경우도 에러가 나지 않을까하고 확인해본것인데 잘 되더라구요.ㅋㅋ

Write a comment.


스프링 3.0의 설정 간편화

Spring/etc : 2009.12.23 11:15


원문: http://blog.springsource.com/2009/12/22/configuration-simplifications-in-spring-3-0/

케이스가 시작한 "스프링 3 간편화" 시리즈 두번째로 스프링의 새로운 @Configuration 애노테이션 및 그와 관련된 지원 기능을 매우 간략하게 소개하고자 한다.

스프링 JavaConfig 프로젝트에 관심을 가지고 있던 사람들이라면 @Configuration 애노테이션 클래스가 스프링 XML 파일과 매우 비슷한 역할을 한다는 것을 알 것이다. 메서드와 애노테이션을 사용하여 스프링 빈을 정의를 선언하는 코드-중심적인 방법을 제공한다. 이러한 것을 POC(Plain Old Configruation)이라고 부를 수도 있겠다. :) XML이 하나도 필요없는 간단한 상활을 일컷는 말이다.

시작해보자. @Configuration 기능을 설명하려고 새로운 스프링 샘플 SVN 저장소에 매우 간단한 프로젝트를 만들어두었다. 그것을 받아서 바로 빌드하고 싶을것이다. 서브버전 클라이언트와 최신 버전 메이븐이 필요하다.

svn co https://src.springframework.org/svn/spring-samples/configuration-basic/trunk configuration-basic
cd configuration-basic
mvn clean test
[...]
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] ————————————————————————
[INFO] BUILD SUCCESSFUL
[INFO] ————————————————————————

이클립스 .classpath와 .project 메타데이터도 체크아웃에 포함되어 있기 때문에 프로젝트를 SpringSprout Tool Suite 또는 m2eclipse 플러그인을 설치한 최신버전 이클립스에서 import 할 수 있을 것이다. 두 경우 모두 File -> Import -> Existing Projects into Workspace를 하면 된다.

AppConfig.java 클래스부터 살펴보자. @Configuration 애노테이션을 추가한 클래스는 XML 설정 기반 스프링 애플리케이션의 app-config.xml과 같은 역할을 한다. 실행시점에 어떻게 객체 인스턴스들이 연관되어 있으며 관리되는지에 대한 "청사진"을 제공하기 때문에 프로젝트를 살펴보기 좋은 시작점이 된다.

@Configuration
public class AppConfig {

    public @Bean TransferService transferService() {
        return new TransferServiceImpl(accountRepository());
    }

    public @Bean AccountRepository accountRepository() {
        return new InMemoryAccountRepository();
    }

}

Granted, 이 예제는 진짜 JDBC Datasource를 사용하지도 않는 매우 간단한 애플리케이션이다. 하지만 이 글의 목적은 기본 개념을 제공하는 것이기 때문에 괜찮다. @Bean을 선언한 메서드는 실행 시점에 스프링 컨테이너에의해 호출되며 반환되는 객체를 스프링 컨테이너가 다른 빈들처럼 관리한다. 다른 빈과의 의존성은 간단하게 다른 빈 메서드를 호출하는 것으로 표현할 수 있다. TransferServiceImpl은 AccountRepository를 생성자 인자로 필요로 하기 때문에 간단하게 accountRepository() 메서드를 호출했다.

경험많은 스프링 사용자라면 이 예제를 보고 "빈 스코프는 어떻게 되는가?"라고 질문할 것이다. 좋은 질문이다. 아시다시피 모든 스프링 빈은 스코프를 가지고 있다. 기본으로 빈의 스코프는 '싱글톤'이며 이것은 스프링 컨테이너 당 하나의 빈 인스턴스만 사용된다는 것을 의미한다. 위의 코드를 보면 accountRepository()를 여러번 호출할 때마다 여러 인스턴스를 만들것 처럼 보이지만 실제로 그렇지는 않다! @Configuration 클래스가 실행 시점에 처리되면 동적으로 (CGLIB을 사용하여) 그 하위 클래스를 만들고, 그 하위 클래스의 @Bean 메서드들은 스코프 개념을 보장하도록 코드를 조작한다.

보시다시피, @Bean 메서드를 정의하는 것은 매우 간단하다. 이제 컨테이너를 동작시키고 저 객체들을 사용해보자.

TransferServiceTest JUnit 시스템 테스트와 transfer100Dollars() @Test 메서드를 보자. 가장 먼저 눈에띄는 것은 AnnotationConfigApplicationContext 사용일 것이다. 이것은 새로운 ApplicationContext 구현체로 @Configuration 클래스를 직접 사용하여 스프링 컨테이너 생성을 지원하도록 스프링 3에 추가되었다. 이 컨텍스트는 AppConfig.class를 생성자 매개변수로 사용하며, 그런다음 TransferService와 AccountRepository 타입의 빈을 getBaen(Class) 메서드를 이용하여 가져온다. 메서드의 남은 부분은 일반적인 JUnit 검증 과정으로 TransferService와 AccountRepository API를 확인하고 예상한대로 잘 동작하는지 확인한다.

public class TransferServiceTest {

    @Test
    public void transfer100Dollars() {
        // create the spring container using the AppConfig @Configuration class
        ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);

        // retrieve the beans we'll use during testing
        AccountRepository accountRepository = ctx.getBean(AccountRepository.class);
        TransferService transferService = ctx.getBean(TransferService.class);

        // create accounts to test against
        accountRepository.add(new Account("A123", 1000.00));
        accountRepository.add(new Account("C456", 0.00));

        // check account balances before transfer
        assertThat(accountRepository.findById("A123").getBalance(), equalTo(1000.00));
        assertThat(accountRepository.findById("C456").getBalance(), equalTo(0.00));

        // perform transfer
        transferService.transfer(100.00, "A123", "C456");

        // check account balances after transfer
        assertThat(accountRepository.findById("A123").getBalance(), equalTo(900.00));
        assertThat(accountRepository.findById("C456").getBalance(), equalTo(100.00));
    }

}

바로 이거다! 간단하고, 순수한 자바이고(사실 저는 개인적으로 이부분에 대해서는 약간의 이견을 가지고 있지만;;), 타입-안정적인 설정이다. 이것이 스프링의 핵심 의존성 주입 기능의 편리하고 강력한 추가기능임을 알았으면 좋겠다.

물론, 오늘 여기서는 매우 간략하게 살펴봤다. @Configuration 클래스로 더 많은 것을 할 수 있으며 자세한 기능은 다음 글에서 설명하도록 하겠다. 하지만 날 기다리지말고 스스로 스프링 3 레퍼런스 문서의 @Configuration 부분을 읽어보길 바란다. 이 예제 프로젝트를 시작점으로 빠르게 새로운 기능의 나머지 부분을 확읺보기 바란다.

피드백을 기대한다. @Configuration과 모든 새로운 스프링 3 기능을 즐기기 바란다. 즐거운 연휴 되시길!

* Thanks to Erich Eichinger for (half-jokingly) coining the phrase 'Plain Old Configuration'. You can take a look at the work he and the Spring.NET team are doing with their similar 'CodeConfig' project here.

ps: 이번글에도 링크가 굉장히 많은데;; 귀찮아서 생략했습니다. 언젠가 안 귀찮을 때 수정하겠습니다.
top

Write a comment.


스프링의 로깅 의존성

Spring/etc : 2009.12.08 17:56


원문: http://blog.springsource.com/2009/12/04/logging-dependencies-in-spring/

봄싹 위키: http://springsprout.org/wiki/1439.do

이 글은 스프링이 결정한 선택 사항들과 개발자들이 스프링을 사용하여 애플리케이션을 만들 때 로깅으로 이용할 수 있는 옵션을 다룬다. 무언가를 많이 변경했기 때문이 아니라, 여러분이 애플리케이션에서 로깅을 구현하고 설정할 때 정보에 근거할 수 있도록 이제는 출시가 임박한 스프링 3.0을 따라야 할 시점이다. 먼저 스프링에 어떤 필수 의존성이 있는지 살펴본 다음, common logging 라이브러리 예제를 사용하여 애플리케이션에 로깅을 설정하는 방법을 좀 더 자세히 살펴보겠다. 예를 들어 메이븐 중앙 스타일 구성물 작명 규약을 사용하는 의존성 설정을 보여주겟다.

스프링 의존성과 스프링에 의존하는 것들

스프링은 광범위한 엔터프라이즈 및 여러 외부 도구를에 대한 연동과 지원을 제공하지만, 내부적으로 필수 의존성을 최소한으로 유지한다. 간단한 경우에 스프링을 사용할 때는 많은 수의 라이브러리를 다운로드(혹은 자동으로) 받을 필요가 없다. 기본적인 의존성 주입은 오직 하나의 외부 의존성을 필요로 하며, 그건 바로 로깅이다.(로깅 옵션에 대해서는 아래의 보다 자세한 설명을 참조하자.) 만약 의존성 관리를 메이븐으로 하고 있다면 로깅 의존성을 명시적으로 설정할 필요도 없다. 예를 들어, 애플리케이션 컨텍트를 만들고 의존성 주입을 이용하고 있다면 애플리케이션에 다음과 같이 설정하기만 하면 된다. 메이븐 의존성은 다음과 같을 것이다.

<dependencies>
   <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>3.0.0.RELEASE</version>
      <scope>runtime</scope>
   </dependency>
</dependencies>

이게 전부다. 기본적인 의존성 주입을 사용하는 경우처럼, 일반저긍로 스프링 API를 컴파일 할 필요가 없다면 scope가 runtime으로 설정해도 된다는 것에 주목하자.

위 예제에서 메이븐 중앙 작명 규약을 사용했기 때문에, 메이븐 중앙 또는 스프링소스 S3 메이븐 저장소와 잘 동작한다. S3 메이븐 저장소를 이용하려면(마일스톤 또는 개발자 스냅샷 버전을 사용하기 위해), 저장소 위치를 메이븐 설정 파일에 명시해야 한다. 전체 배포는 저장소는 다음과 같다.

<repositories>
   <repository>
      <id>com.springsource.repository.maven.release</id>
      <url>http://s3.amazonaws.com/maven.springsource.com/release/</url>
      <snapshots><enabled>false</enabled></snapshots>
   </repository>
</repositories>

마일스톤 저장소는 다음과 같다.

<repositories>
   <repository>
      <id>com.springsource.repository.maven.milestone</id>
      <url>http://s3.amazonaws.com/maven.springsource.com/milestone/</url>
      <snapshots><enabled>false</enabled></snapshots>
   </repository>
</repositories>

스냅샷은 저장소는 다음과 같다.

<repositories>
   <repository>
      <id>com.springsource.repository.maven.snapshot</id>
      <url>http://s3.amazonaws.com/maven.springsource.com/snapshot/</url>
      <snapshots><enabled>true</enabled></snapshots>
   </repository>
</repositories>

스프링소스 EBR을 사요하려면 의존성을 나타낼 때 다른 이름 규약을 사용해야 한다. 이름은 보통 유추하기 쉽다. 예를 들어 이번 경우에는 다음과 같다.

<dependencies>
   <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>org.springframework.context</artifactId>
      <version>3.0.0.RELEASE</version>
      <scope>runtime</scope>
   </dependency>
</dependencies>

물론 저장소도 명시적으로 설정해 줘야 한다.

<repositories>
   <repository>
      <id>com.springsource.repository.bundles.release</id>
      <url>http://repository.springsource.com/maven/bundles/release/</url>
   </repository>
</repositories>

만약 의존성을 손으로 관리한다면, 위 저장소 설정에 보이는 URL은 브라우저로 볼수가 없고, http://www.springsource.com/repository에 사용자 인터페이스가 있으니 검색하여 의존성을 다운 받을 수 있다. 또한 이 사이트에는 간편한 메이븐과 Ivy 설정이 있으니 복사하여 붙여넣기로 쉽게 해당 도구에서 사용할 수 있다.

만약 Ivy를 사용하여 의존성 관리하는 것을 선호한다면 위와 비슷한 이름과 설정 옵션이 관리 시스템에 있거나 예제 코드를 살펴보기 바란다.

로깅

로깅은 매우 중요한 스프링 의존성이다. 왜냐하면 a) 유일한 외부 의존성이자, b) 모두가 자신이 사용하는 도구에서 무언가 출력되는 것을 보고 싶어하며, c) 스프링은 로깅에 의존성을 가지는 다양한 툴과 연동하기 때문이다. 애플리케이션 개발자의 목적 중 하나는 보통 외부 컴포넌트를 포함한 전체 애플리케이션에 대해 중앙의 통합된 로깅 설정을 가지는 것이다. 로깅 프레임워크가 다양해지면서 예전보다 선택하기가 더 어려워졌다.

스프링에 있는 필수 로깅 의존성은 Jakarta Commons Logging API(JCL)이다. JCL을 컴파일하고 JCL Log 객체를 스프링 프레임워크를 확장한 클래스에서 볼 수 있다. 스프링의 모든 버전에서 동일한 로깅 라이브러리를 사용하는 것이 사용자에게 중요하다. 스프링을 확장한 애플리케이션이더라도 뒷 단의 호환성이 보장되기 때문에 이전하기가 용이하다. 우리는 스프링의 모듈 중 하나를 명시적으로 commons-logging(JCL)에 의존하게 하고 다른 모듈들이 컴파일 시점에 해당 모듈에 의존하도록 하는 방법을 사용한다. 예를 들어, 메이븐을 사용하고 있으며, 어디서 commons-loggins에 대한 의존성을 가져와야 하는지 궁금하다면, 스프링에서 가져오도록 하고 명시적으로는 spring-core 모듈에서 가져온다.

commons-logging의 좋은 점은 애플리케이션이 동작하는데 필요한 것이 아무것도 없다는 것이다. 런타임 감지 알고리즘을 가지고 있어서 클래스패스에 잘 알려진 로깅 프레임워크가 있다면 적절한 것을 찾아 사용하도록 되어있다.(또는 여러분이 어떤것을 사용하고 싶은지 알려줄 수도 있다) 만약에 사용할 수 있는 것이 아무것도 없다면 JDK(java.util.logging 또는 줄여서 JUL)로부터 로그를 가져온다. 여러분의 스프링 애플리케이션이 대부분의 경우 잘 동작하며 잘 로깅 된다는 것을 알아야 하며, 그것은 중요하다.

불행히도, commons-logging의 안좋은 점은 역시 런타임 감지 알고리즘이다. 만약 시간을 되돌려 스프링을 새로운 프로젝트로 시작할 수 있다면 우리는 다른 로깅 의존성을 사용했을 것이다. 아마도 첫번째 선택은 많은 사람들이 애플리케이션에서 스프링과 함께 사용하고 있는 Simple Logging Facade for Java(SLF4J)일 것이다.

commons-loggins을 교체하는 것은 쉽다. 실행중에 클래스패스에 없도록 만들자. 메이븐에서 의존성을 제외할 수 있다. 스프링 의존성 선언 방법으로 인해 다음과 같이 한번만 선언하면 된다.

<dependencies>
   <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>3.0.0.RELEASE</version>
      <scope>runtime</scope>
      <exclusions>
         <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
         </exclusion>
      </exclusions>
   </dependency>
</dependencies>

이제 이 애플리케이션은 JCL API가 클래스패스에 없으니 깨질 것이다. 새로운 것을 제공하여 그것을 고쳐보자. 다음 절에서 우리는 어떻게 JCL 구현체의 대안으로 SLF4J를 사용하는지 예제를 살펴보겠다.

SLF4J 사용하기

SLF4J는 연동할 다른 프레임워크를 찾는 작업을 실행중에 하지 않고 컴파일 시점에 바인딩 하기 때문에 commons-loggins 보다 보다 깔끔한 의존성과 실행시 보다 더 효율적이다. 이것은 즉 실행중에 여러분이 어떤 것을 사용하고 싶은지 보다 명시적으로 선언하고 그것을 적절하게 설정해야 한다는 뜻이다. SLF4J는 여러 로깅 프레임워크에 대한 바인딩을 지원하기 때문에 여러분들이 기존에 사용하고 있던 것을 선택하고 해당 설정과 관리로 바인딩할 수 있다.

SLF4J는 JCL을 포함한 여러 로깅 프레임워크에 대한 바인딩을 제공한다. 또한 그 반대로 마찬가지다. 다른 로깅 프레임워크와 자신을 연결해준다. 따라서 SLF4J를 스프링에서 사용하기 위해서는 commons-logging 의존성을 SLF4J-JCL 브릿지 의존성으로 교체해야 한다. 그렇게 한번 하면 스프링 내부의 로깅 호출이 SLF4J에 대한 로깅 호출로 바뀐다. 따라서 만약 애플리케이션에서 다른 라이브러리들도 해당 API를 사용하고 있다면, 로깅을 설정하고 관리할 곳은 한 부분이다.

일반적인 선택은 스프링에서 SLF4J로 연결하고, SLF4J에서 Log4J로 명시적인 바인딩을 하는 것이다. 4개의 의존성을  명시적으로 제공해야 한다. brigde, SLF4J API, binding to Log4J, Log4J 구현체. 메이븐에서 다음과 같이 설정할 수 있다.

<dependencies>
   <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>3.0.0.RELEASE</version>
      <scope>runtime</scope>
      <exclusions>
         <exclusion>
           <groupId>commons-logging</groupId>
           <artifactId>commons-logging</artifactId>
         </exclusion>
      </exclusions>
   </dependency>
   <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>jcl-over-slf4j</artifactId>
      <version>1.5.8</version>
      <scope>runtime</scope>
   </dependency>
   <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.5.8</version>
      <scope>runtime</scope>
   </dependency>
   <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.5.8</version>
      <scope>runtime</scope>
   </dependency>
   <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.14</version>
      <scope>runtime</scope>
   </dependency>
</dependencies>

로깅을 하기위해서는 좀 많은 의존성처럼 보인다. 실제로 그렇긴 하지만 꼭 그래야 하는건 아니며 순수commons-logging 보다 더 잘 동작할 것이다. 특히 OSGi 플랫폼같이 제약적인 컨테이너를 사용한다면 말이다. 이른바 실행시점이 아니라 컴파일 시점에 바인딩을 하기 때문에 성능상 장점을 얻을 수 있다.

SLF4J 사용자들 사이에서 보다더 일반적인 선택은 Logback에 지접 바인딩하여 과정을 짧게 하고 의존성을 더 줄이는 것이다. Logback이 SLF4J를 지겁 구현하기 때문에 추가적인 바인딩 과정을 제거해주기 때문에, 4개가 아니라 오직 두 개 라이브러리만 필요하다. (jcl-over-slf4j와 logback). 만약 그렇게 하면 slf4j-api 의존성 자체로 명시적인 의존성에서 제거할 필요가 있을지 모르겠다. 오직 한 버전 API 만 클래스패스에서 사용하길 원하기 때문이다.

Log4J 사용하기

많은 개발자들은 Log4J를 로깅 프레임워크로 사용하고 설정하고 관리한다. 효율적이며 잘 만들어졌다. 실제로 스프링을 만들고 테스트할 때 실행시에 사용하는 것이기도 하다. 스프링 또한 Log4j 설정과 초기화를 간편히 할 수 있는 것들을 제공한다. 따라서 몇몇 모듈은 Log4J에 대한 부가적인 컴파일 시점 의존성을 가지고 있다.

Log4j를 기본 JCL 의존성으로 사용할 때 필요한 것은 Log4J를 클래스패스에 두는것이 전부이다. 그리고 (log4j.properties 또는 log4j.xml을 클래스패스 루트에) 설정 파일을 제공하면 된다. 따라서 메이븐 사용자는 다음과 같이 의존성 선언을 하면된다.

<dependencies>
   <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>3.0.0.RELEASE</version>
      <scope>runtime</scope>
   </dependency>
   <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.14</version>
      <scope>runtime</scope>
   </dependency>
</dependencies>

그리고 다음은 콘솔에 로깅하는 log4j.properties다.

og4j.rootCategory=INFO, stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %t %c{2}:%L – %m%n

log4j.category.org.springframework.beans.factory=DEBUG

네이티브 JCL과 런타임 컨테이너

많은 사람들이 스프링 애플리케이션을 JCL 구현체 자체를 제공하는 컨테이너에서 구동한다. IBM 웹스피어 애플리케이션 서버(WAS)가 그중 하나이다. 이것은 보통 문제를 야기하고, 불행히도 정답은 없다. commons-logging을 애플리케이션에서 간단하게 제외하는 것이 대부분 상황에서 충분한건 아니다.

정리하자면: 문제는 JCL 또는 common-logging 자체가 아니라 commons-logging을 다른 프레임워크(보통 Log4J)에 바인딩하는 것과 관련이 있다. commons-logging이 런타임 탐색하는 방법이 몇몇 컨테이너가 사용하고 있는 예전 버전(1.0)과 현재 대부분의 사람들이 사용하고 있는 버전(1.1)과 다르기 때문이다. 스프링은 JCL API에서 별다른 것을 사용하지 않기 때문에 깨질것은 없지만, 조만간 로깅을 하려는 스프링 또는 여러분의 애플리케이션이 Log4J로 바인할 때 동작하지 않을 수 있다.

그런 경우 WAS를 사용할 때는 클래스로더 계층 구조(IBM은 이것을 "parent last"라 부른다.)를 변경하여 컨테이너가 아니라 애플리케이션이 JCL 읜존성을 제어하게 할 수 있다. 하지만 이 방법이 항상 가능한 건 아니지만,  여러분이 사용하는 컨테이너틔 버전과 기능에 따라 다양한 대안들이 공공연히 제시되고 있다.
top

  1. Favicon of http://blog.lckymn.com BlogIcon Kevin 2009.12.09 00:36 PERM. MOD/DEL REPLY

    전 요즘 Commons Logging과 log4J는 사용 안하고 SLF4J와 LOGBack만 씁니다. :)
    사용해 보니 여러가지로 맘에 들더라구요. NDC보다 MDC가 더 활용가치가 높기도 하구요.

    근데, 대충 본바로...
    "이 기사는 스프링이 결정한..." 이부분에서 '음? 무슨 기사지?' 라는 생각에 원문을 보니
    article이라고 되어 있네요. 여기 나온 article은 '기사' 보다는 '글'이 나을것 같은데요.
    article은 기사라는 뜻으로도 쓰이지만, 블로그에 올려놓은 글처럼
    일반적으로 '글'을 article이라고 많이 하니까요.

    평범한(vanilla) commons-logging 의 경우 vanilla 는 평범한 보다는
    '꾸미지 않은', '다른것이 더해지지 않은' 이란 뜻으로 쓰였으니,
    다른 수식어 없이 그냥 'commons-logging' 이라고 하시거나
    '순수 commons-logging' 정도가
    더 어울리지 않을까 하는 지극히 개인적인 생각이 드는군요. :)

    평범한 이라고 하니 commons-logging이 평범하다는 듯한 느낌이
    나서요. 물론 바닐라 라는 단어를 넣긴 하셨지만,
    이거 없이도 이해 되는게 낫지 않을까 하는 생각이 들어서요.

    Favicon of http://whiteship.me BlogIcon 기선 2009.12.09 11:09 PERM MOD/DEL

    와우 감사합니다.

    사실 그런 의미에서 봄싹 위키 링크를 걸어둔거죠.ㅋㅋ 누구나(사실 봄싹 사이트에 가입해야지만 가능하지만 말이죠) 편집하실 수 있도록 말이죠.

    봄싹 코드에 적용해봐야겠어요. SLF4J와 LogBack!

Write a comment.


[전자정부 개발프레임워크 교육자료] 표준 프레임워크 개요 PPT 감상문

Spring/etc : 2009.10.27 17:45


6 페이지

개발프레임워크는 단위컴포넌트, 래퍼(Wrapper), 정적인아키텍처, 동적인아키텍처로 구성되어 있으며, 일반적으로 단위 컴포넌트는 오픈소스나 상용 솔루션을 도입함.

음.. 그렇구나. 개발 프레임워크는 네 가지로 구성 되는 구나. 근데 도통 모르겠네, 래퍼는 대충 뭔지 알겠는데, 단위 컴포넌트, 정적 아키텍처, 동적 아키텍처는 뭐야.

단위 컴포넌트는 특정한 기술적/업무적 목적을 지원하는 블라브라.. 아 몰라 몰라;;
정적 아키텍처는 객체들간의 연관 관계를 다루고 동적 아키텍처는 객체들간의 상호작용을 다룬다고??? 이게 뭔소리야!!!!! 아 놔.. @_@... 패스

58 페이지(MVC)

// 업무로직은 controller가 담당, 여러 View에서 재사용.

으응??? 진짜????? 컨트롤러가 담당한다고? ㅋㅋㅋㅋㅋ 여러 뷰에서 뭘 재사용해.. 뭘.. 컨트롤러를?? 흠..;; 이것 참...

 59 페이지(ORM)

일반적인 개발
매핑 적용: 테이블 컬럼과 자바 클래스간의 직접적인 매핑 필요
유연성: SQL 변경시 코드를 직접 변경하고 배포해야 함
표준 패턴: 패턴 없음
DB 제어: 직접적으로 DB제어 가능
활용 기술: SQL

ORM 구축
매핑 적용: 개발자는 직접 객체지향 관점에서 처리 가능
유연성: 매핑 정보의 수정만으로 적용 가능
표준 패턴: 매핑 정보, XML 등이 템플릿 형태로 적용됨
DB 제어: Mapping의 경우 직접적인 제어가 어려울 수 있음
활용 기술: Persistence 프레임워크 (Hibernate, iBatis)

이야.. ORM 좋네. 매핑 정보만 수정하면 배포 안 해도 되는거야?? 대신 DB 제어는 직접적으로(?) 못해?? 진짜?? ORM도 SQL 쓰지 안쓰나.. 흠.. 희한하네..

61 페이지(DI)

DI(Dependency Injection)는 컴포넌트 간 연관성 및 참조 정보를 직접적으로 코드 내에서 가지는 것이 아니라, 외부 파일 등에 연관 정보를 설정하고, WAS가 기동 하는 Run-Time시에 연관 정보를 가지도록 하는 것임

일반적인 개발
컴포넌트: EJB 컴포넌트 활용 (무겁고 복잡함)
유연성: 참조 변경이나 컴포넌트 재사용시 어려움 (컴포넌트 내부 코드 변경 필요)
표준 패턴: 패턴 없음
연관 제어: 연관성 파악이 어려움 (전체 코드 분석 필요)
활용 기술: EJB

DI 구축
컴포넌트: 순수 자바 코드 (POJO) 활용하여 컴포넌트 구현 Lightweight Component 체계
유연성: 쉽게 참조 변경 가능하고 재사용 가능 (컴포넌트 내부 코드 변경 불필요)
표준 패턴: 매핑 정보, XML 등이 템플릿 형태로 적용됨
연관 제어: 설정 파일 만으로 연관성 파악 가능
활용 기술: Component 프레임워크 (Spring, HiveMind)

DI하기 참~~ 어렵구만, WAS가 있어야 돼. 젠장...

근데, 정작 중요한 "테스트"에 대한 얘기는 거의 없네.. "테스트 도구" 얘기만 있고.. 테스트는 다른 PPT에서 다루나.

뭐 일단은 재밌네!! 캬캬캬.

다른 것도 봐야지
top

  1. Favicon of https://helols.tistory.com BlogIcon is윤군 2009.10.27 22:23 신고 PERM. MOD/DEL REPLY

    살살.. ㅎㅎ

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2009.10.27 22:38 신고 PERM MOD/DEL

    이정도면 살살아냐? 난 이제 영어 공부나 해야지

  2. Favicon of http://blog.lckymn.com BlogIcon Kevin 2009.10.28 14:51 PERM. MOD/DEL REPLY

    무슨 개그 콘서트 대본 인줄 알았네요...@_@;;;

    원본은 어디서 볼수 있나요?

    Favicon of http://whiteship.me BlogIcon 기선 2009.10.28 15:02 PERM MOD/DEL

    http://www.egovframe.go.kr/

    자료실 밑에 교.육.교재에 있습니다.

    Favicon of http://blog.lckymn.com BlogIcon Kevin 2009.10.28 21:44 PERM MOD/DEL

    고맙습니다. :)

    Favicon of http://whiteship.tistory.com BlogIcon 기선 2009.10.28 22:37 PERM MOD/DEL

    ㅎㅎ재밌게 보세요~

Write a comment.


스프링의 이메일 기능 지원과 테스트를 살펴보자

Spring/etc : 2009.07.27 12:20


스프링이 지원하는 이메일은 JavaMail과 JAF라는 것이 있습니다. 사용법은 간단하니.. 다음에 심심할 때 살펴보기로 하고, 지금은 사부님이 올리신 글과 관련 된 부분을 찾아보는게 급선무입니다.

스프링 이메일 기능은 context.support 모듈에 들어있습니다. 주요 클래스는 o.s.mail.javamail에 들어있는 JavaMailSender 인터페이스와 그 구현체인 JavaMailSenderImpl 클래스입니다. 인터페이스의 API를 읽어보면 다음과 같은 내용이 있습니다.

...

Clients should talk to the mail sender through this interface if they need mail functionality beyond SimpleMailMessage. The production implementation is JavaMailSenderImpl; for testing, mocks can be created based on this interface. Clients will typically receive the JavaMailSender reference through dependency injection.

...

The entire JavaMail Session management is abstracted by the JavaMailSender. Client code should not deal with a Session in any way, rather leave the entire JavaMail configuration and resource handling to the JavaMailSender implementation. This also increases testability.

A JavaMailSender client is not as easy to test as a plain MailSender client, but still straightforward compared to traditional JavaMail code: Just let createMimeMessage() return a plain MimeMessage created with a Session.getInstance(new Properties()) call, and check the passed-in messages in your mock implementations of the various send methods.

즉, 이 API를 만든 의도에 사용성 편의 뿐만 아니라, 테스트 편의성도 포함되어 있다는 암시를 읽어낼 수 있습니다. JavaMail의 Session API를 사용하지 않고 스프링의 JavaMailSender를 목킹해서 테스트 하라는 것인데, 왜 그렇게 했는지는 맨 마지막 부분의 JavaMail의 Session API 사용법(Session.getInstance(new Properties())에서 볼 수 있습니다. 바로 static 메서드입니다.

JavaMail 레퍼런스에서 그 사용법을 보면, 다음과 같은 코드로 JavaMail을 이용하는 모습을 볼 수 있습니다.

//메시지를 만들고,,
     Properties props = new Properties();
     props.load(new FileInputStream(propfile));

     Session session = Session.getInstance(props, null);
     MimeMessage msg = new MimeMessage(session);

...

//전송합니다.
    // Set the content for the message and transmit
    msg.setContent(mp);
    Transport.send(msg);

코드 대부분을 생략했습니다. 중요한 부분은 위에 다 나와있습니다. 바로 static 메서드를 사용한다는 것이 중요한 부분입니다.

이런 API 사용을 클래스를 단위 테스트 하려면 막막합니다. 도무지 static 메서드를 호출하는 부분을 mock으로 바꿀 수가 없습니다. 그렇다고 테스트를 하는데 실제로 메일을 매번 보내기도 뭐하고 말이죠. 그래서 테스트 하려면 static 메서드 호출을 사용한 클래스를 거의 다시 만들다시피 구현한 stub을 만들어서 테스트 해야 하는데 이건 엄청난 수고가 필요합니다. JavaMail 예를 들면 거의 Transport를 테스트용으로 다시 구현해서.. sendMessage에서 실제로 메일을 보내지 않고 그냥 보내는 메시지 목록에 메시지만 모아두는 식의 작업이 필요해집니다. 그리고 테스트 할 떄는 그런 스텁 Transport를 사용하는 또 다른 스텁 MailSender가 필요해지겠죠.(실제로 이 작업들은 스프링의 JavaMailSenderTests에서 수행하고 있습니다.)

하지만, 테스트를 편하게 하는 방법이 아주 없는 건 아니었습니다. 오늘 톱님께서 올리신 글을 보면 static 메서드를 호출하는 코드를 비교적 편하게 테스트하는 방법 세 가지를 알 수 있습니다.

하나는 JavaMailSender처럼 static 메서드 호출 부분을 랩핑한 클래스를 만들고, 그 클래스를 목킹한 다음 해당 메서드가 호출되는지 테스트하는 것입니다. 그렇게 만들어 두면, 테스트 하려는 대상이 JavaMail의 Transport.send 같은 static 메서드를 호출하지 않고, 그것을 사용한 JavaMailSender를 사용하기 때문에 JavaMailSender의 mock을 만들고 그 객체의 send가 호출될 때 어떤걸 하라고 mocking 한다던지 해서 호출이 제대로 됐는지, 어떤 메시지가 넘어갔는지 등을 확인할 수 있겠습니다.

두 번째 방법은 로드존슨이 만들었다는 AspectJ를 이용하는 방법이고, 세 번째 방법은 PowerMock을 이용하는 방법인데, 둘 다 결국 바이트코드를 조작해서 static 호출 부분을 mock으로 호출로 교체하는 기술 인듯합니다. 이 두 가지는 일단 논외로 치

결론은.. 스프링의 JavaMailSender를 사용하면 JavaMail의 static 메서드 호출과 관련하여 테스트를 어떻게 작성할까 고민할 필요없이, JavaMailSender를 목킹해서 테스트를 만들면 된다는 것입니다.

덤으로 JavaMail의 static 메서드 호출을 사용한 JavaMailSender의 테스트 클래스를 보면, static 메서드 호출을 하는 클래스에 대한 테스트 실마리를 얻을 수 있습니다. static 메서드를 호출해서 가져오는 객체를 가져오는 부분을 별도의 메서드로 분리하고 그 부분을 테스트 용으로 재구현하고 그것을 테스트에서 사용하는 방법인데.. 이거 이거.. 귀찮아서 원... @_@..  그래서 static은 테스트의 적인가 봅니다. 그래도 이길 수 있는 적이라는거..
top

  1. openmaya 2010.01.18 12:08 PERM. MOD/DEL REPLY

    굉장히 예전에 쓰신글을 이제야 봅니다 ㅋstatic 메서드와 호출관련해서 비슷한 경험을 한적이 있는데요. 다름이 아니라 HTTP호출을 하는 클래스를 static으로 선언한 경우 입니다. 데이터 자체는 openapi를 이용해 가져오고 HTTP 호출을 하기위해서는 인증을 위해 헤더값 추가까지 하는 경우에 하려는 것에 비해 Method클래스 등등 많은 작업이 필요하게 되는데요. 이 부분이 다른 분이 작성한 부분이라서 결국엔 랩핑클래스를 만들고 그 클래스를 테스트 해야 했지요. 이런경우에 단점이 기존의 다른 분이 만드신 코드들은 래핑클래스를 사용하지 않는 상황이라서 코드가 이원화 되어버린 상황이랄까요.

    Favicon of http://whiteship.me BlogIcon 기선 2010.01.19 10:52 PERM MOD/DEL

    "HTTP호출을 하는 클래스를 static으로 선언한 경우"

    어이쿠.. 그렇군요. 스프링 3.0에 추가된 RestTemplate인가하는 클래스랑은 대조적이네요.

Write a comment.


What's new in Spring 3.0?

Spring/etc : 2009.04.20 19:34


참조: http://www.epril.com/resources/spring3/reference/html/ch02.html

요약 및 편역합니다.

2.1 자바 5

전페 프레임워크 코드를 제네릭, 가변인수(varargs) 같은 자바 5 기능을 사용하도록 수정했다. FactoryBean, 스프링 AOP, ApplicationListener 코드에 제네릭을 활용했다. 또한, TrasactionCallback과 HibernateCallback과 같은 콜백 인터페이스들은 제네릭한 결과를 반환하도록 수정했다. 스프링 코어 코드베이스를 전반적으로 자바 5에 최적화 시켰다.

스프링의 TaskExecutor 추상화 계층을 자바 5의 java.util.concurrent 시설과 밀접하게 통합되도록 수정했다. JSR-236(자바 EE 6 Concurrency Utilies)에 포함되어 있는 Callable, Future, ExecutorService 어댑터, ThreadFactory 연동 등을 지원한다. 또한 (EJB 3.1 @Asynchronous 또는) @Async 애노테이션을 사용하여 비동기 메서드 호출도 지원한다.

2.2. 개선한 문서

추가된 기능에 맞게 3.0 문서 작업을 새로 했고, 검증을 했지만 그래도 틀린 부분이 있다면 이슈를 등록해 달라.

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

다음과 같은 모듈로 새롭게 개정했고 소스 트리당 모듈.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

* 더 이상 모든 구성요소를 담고 있던 spring.jar는 제공하지 않는다.

새로운 스프링 빌드 시스템을 사용한다. 그 시스템은 다음 기능을 제공한다.

      Ivy 기반 "스프링 빌드" 시스템
      일관된 배포 절차
      일관된 의존성 관리
      일관된 OSGi manifest 생성

2.4. 새로운 기능 살펴보기

다음은 스프링 3.0이 새롭게 제공하는 기능이다. 이 기능들을 자세히 살펴보겠다.

      Spring Expression Language
      IoC enhancements/Java based bean metadata
      Object to XML mapping functionality (OXM) moved from Spring Web Services project
      Comprehensive REST support
      @MVC additions
      Declarative model validation
      Early support for Java EE 6

2.4.1. 자바 5에 맞게 핵심 API 업데이트

BeanFactory 인터페이스가 타입에 맞는 빈을 반환한다.

      T getBean(Stringname, Class<T> requiredType)
      Map<String, T> getBeansOfType(Class<T> type)

스프링의 TaskExecutor 인터페이스가 java.util.concurrent.Executor를 상속 받는다.

      AsyncTaskExecutor를 확장하여 표준 Callables와 Futures를 지원한다.

새로운 자바 5 기반의 converter API와 SPI
 
      stateless ConversionService와 Converters
      표준 JDK PropertyEditor 대체제

타입을 가지고 있는 ApplicationListener<E>

2.4.2. 스프링 EL(Expression Language)

스프링은 통합 EL과 비슷한 EL을 토입했다. EL은 XML 정의와 애노테이션 기반 빈 설정에서 사용할 수 있다. 이 기능에 대한 자세한 설명은 Spring Expression Language (SpEL).장을 참조하라.

스프링 EL은 모든 스프링 포트폴리오 제품에서 사용할 수 있는 단일 EL을 제공하기 위해 만들었다.

다음은 데이터베이스 설정 프로퍼티에 EL을 사용하는 예제다.

<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 voidsetKeyGenerator(KeyGenerator kg) { … }
}

2.4.3. IoC 컨테이너

2.4.3.1. 자바 기반 빈 메타데이타

JavaConfig 프로젝트의 몇몇 핵심 기능을 스프링 프레임워크로 가져왔다. 즉 다음의 애노테이션을 직접 사용할 수 있다는 뜻이다.
   
      @Configuration
      @Bean
      @Primary
      @Lazy
      @Import
      @Value

다음은 JavaConfig 기능을 사용하는 기본적인 빈 설정 예제다.

@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() {
        // wire up a session factory using
        // AnnotationSessionFactoryBean
        asFactoryBean.setDataSource(dataSource());
        return (SessionFactory) asFactoryBean.getObject();
    }

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

이 것이 동작하게 하려며 애플리케이션 컨텍스트 XML 설정 파일에 다음과 같이 컴포넌트 스캔을 추가한다.

<context:component-scan
    base-package="com.myco.config"/>
 
2.4.3.2. 애노테이션을 활용한 팩토리 빈 정의

FactoryBean은 스프링 컴포넌트 정의와 표준 컴포넌트-스캔 기술을 사용한 등록 방식으로 정의할 수 있다. 자세한 내용은 Factory Bean Definitions using annotations을 참조하라.

2.4.4. Data 단

스프링 웹 서비스 프로젝트에서 객체(Object)를 XML로 맵핑하는 기능(OXM)을 스프링 프레임워크로 가져왔다, 이 기능은 org.springframework.oxm 패키지에 들어있다. OXM의 자세한 사용법은 Marshalling XML using O/X Mappers를 참조하라.

2.4.5. Web 단

웹 단에서 가장 흥미로운 새 기능은 RESTful 웹 서비스와 웹 애플리케이션 지원 기능이다. 또한 새로운 애노테이션도 사용할 수 있다.

2.4.5.1. 방대한 REST 지원

RESTful 애플리케이션을 만드는 서버쪽 지원은 기존의 MVC 웹 프레임워크에서 주도적인 역할을 하는 애노테이션에 대한 확장 기능으로 제공한다. 클라이언트쪽 지원은 RestTemplate 클래스로 제공한다. 이 둘 모두 HttpConverter를 사용하여 객체와 그것에 대한 HTTP 요청과 응답 사이를 변환 해준다.

MarhsallingHttpMessageConverter는 앞서 언급한 Object to XML 맵핑 기능을 사용한다.

자세한 내용은 REST support를 참조하라.

2.4.5.2 @MVC additions

@CookieValue와 @RequestHeaders 애노테이션이 추가됐다. Mapping cookie values with the @CookieValue annotationMapping request header attributes with the @RequestHeader annotation을 참조하라.

2.4.6 선언적인 모델 검증

하이버네이트 검증기, JSR 303

작업중... 스프링 3.0 M3 배포에 포함되어 있지 않다.

2.4.7 발빠른 자바 EE 6 지원

새로운 애노테이션 @Async (or EJB 3.1's @Asynchronous 애노테이션)을 사용하여 비동기 메서드 호출을 지원한다.

JSF 2.0, JPA 2.0, 기타 등등

작업중... 스프링 3.0 M3 배포에 포함되어 있지 않다.


top

  1. Favicon of https://helols.tistory.com BlogIcon is윤군 2009.04.21 20:13 신고 PERM. MOD/DEL REPLY

    부지런하네요;;ㅋㅋ

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2009.04.21 21:14 신고 PERM MOD/DEL

    ㅎㅎ별말씀을~

Write a comment.


우와~ 스프링 tc 서버다!!

Spring/etc : 2009.04.03 10:55


참조: http://www.springsource.org/node/1251

베타 버전이네요. 음.. 설치부터 간단하지가 않군요. 세 가지 구성요소를 설치해야 하는데, 하나는 tc 서버, 나머지는 AMS와 AMS 에이전트 입니다. 이 둘은 예~전에 한 번 설치해서 본적이 있었는데, 서버나 애플리케이션의 리소스 상황을 보여주고 관리하는데 편리한 기능을 제공하는 시스템이었습니다.

사용자 삽입 이미지

이 그림 한 장이면 이 세 개의 구성요소 간의 관계와 어떤 형태로 설치할 수 있는지 한 눈에 볼 수 있습니다.

AMS Sever, AMS Agent, tc Server를 한 컴퓨터에 모두 설치할 수도 있지만, 저렇게 나눠서 설치할 수도 있으며 그럴 때 AMS Server는 한 곳에만 설치하면 되고, 여러 컴퓨터에 각각 tc Server를 (한개 또는 여러개)설치하고  AMS Server로 정보를 보내줄 AMS Agent도 역시 컴퓨터 마다 하나씩만 설치하면 됩니다.

즉.. 이 들간의 관계를 그려보면 다음과 같다는 것을 알 수 있습니다.

사용자 삽입 이미지

드디어 나올 것이 나왔네요. 기쁩니다!! 이 녀석으로 개발을 시작해야겠습니다.
top

TAG tc Server
  1. Favicon of https://helols.tistory.com BlogIcon is윤군 2009.04.03 12:22 신고 PERM. MOD/DEL REPLY

    ㄱㄱㄱ~~ ㅋㅋ

    Favicon of http://whiteship.me BlogIcon 기선 2009.04.03 13:27 PERM MOD/DEL

    응 이거 쓰자~

  2. slgmoney 2009.04.06 12:20 PERM. MOD/DEL REPLY

    1. tcserver-windows-beta3.sfx.zip 다운로드
    2. 압축 해제
    3. \tc서버\tcserver-windows-beta3.sfx\tcserver-windows-beta3 로 이동
    4. run.bat

    -- 인스톨 중 Checking for compatible JVM... funning Java6 : tc Server AMS will not run under Java6.

    이런 메세지 뜬 후에, 인스톨이 done 되긴 했는데요.

    그 이후에 quick setup 시키면,,

    Please ignore references to missing tools.jar
    java.lang.NoClassDefFoundError: org/apache/toors/ant/launch/Launcher
    WARNING: Default charset MS949 not supported, using ISO-8859-1 instead
    Exception in thread "main" Deleting temporary JRE
    ...hit return...

    이렇게 뜨고,, 인스톨메뉴로 돌아갑니다;,, 도와주세요;;

    Favicon of http://whiteship.me BlogIcon 기선 2009.04.06 13:04 PERM MOD/DEL

    저도 안해봐서 모르겠지만 기본 인코딩을 MS949 말고 ISO-8859-1을 써보시죠. 에러 메시지 경고 문구가 그렇게 하라네요. @_@

  3. slgmoney 2009.04.07 12:00 PERM. MOD/DEL REPLY

    WARNING: Default charset MS949 not supported, using ISO-8859-1 instead

    이 경고는 계속 나오지만 무시해도 되는것 같군요,

    디렉토리를 C:\springsource\tcServertmp 여기로 바꾸고 하니까,, 해결 됐어요,,

    꼭 그래야 하는건지는 모르지만 일단,, 설치는 다 해봤는데,, 화면이 아직 눈에 안익네요,, ,

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2009.04.07 16:44 신고 PERM MOD/DEL

    ㅊㅋㅊㅋ성공하셨군요!!

Write a comment.


스프링 프레임워크 트레이닝 갈까말까

Spring/etc : 2009.03.23 10:56


참조: http://www.springsource.com/training/spr001/icn20090525

고민되네요. 참석하고 싶은데 걸리는게 조금 있습니다.

일단 돈이 문제입니다. 호주 달러로 거의 3000달러인데 그것도 4월 24일 전에 등록해야 2995달러고, 그 뒤에는 3230달러입니다. 세일 가격에 등록한다고 했을 때 한화로 300만원이 필요합니다.

일정이 문제입니다. 결혼식이 5월 30일인데 교육 일정이 25~28일입니다. 결혼식에 한참 신경써야 할 시기인데 색시가 서운하거나 내가 교육에 집중하지 못 할 일이 생기지는 않을지 걱정입니다.

그래도 가고 싶은 이유는 일단 실습 교육이라는 겁니다. 스프링소스 직원은 어떤 스타일로 스프링을 사용하는지 볼 수 있는 절호의 기회인 듯 합니다.

두 번째는 영어 실력 테스트입니다. 지난 번 스프링 컨퍼런스에 가서 느낀점은 스프링 보다는 영어가 중요하다는 거였습니다. 스프링은 영어를 마스터 하고 나서 해도 늦지 않겠다고 느꼈습니다. 그런데 게을러지다 보니까 쉬운거만 하게 되고 영어 공부보다는 스프링 공부가 쉬우니까 나태해졌는데.. 그런 제 자신에 경각심을 줄겸 영어 열공에 목표도 줄겸.. 여러모로 영어 학습에 기름을 부울 수 있는 계기가 될 것 같습니다.

세 번째는 스프링 자격증입니다. 스프링 자격증이 있다는 걸 모르시는 분들도 많을텐데요. 스프링 자격증을 따려면 교육 과정에 참여해야 합니다. 예외도 있긴 하지만 극히 드문 경우 같구요. 이번 교육에 참요하면 자격증 시험 등록비를 깍아 준다고 합니다. 보통 150$를 깍아 준다고 하니까 괜찮은 떡밥이라고 생각됩니다.

네 번째는 희소성입니다. 이번이 아니면 언제 또 한국에 와서 교육을 해줄지 모르기 때문에 오히려 이번에 교육을 받는게 낫지 않을까 하는 생각입니다.

시간과 돈에 여유가 있으신 분들은 참석하시면 좋을 듯합니다. 아웅~~~ 가고 싶다!!
top

  1. aStRe 2009.03.23 12:06 PERM. MOD/DEL REPLY

    여유되시면~ 가세요!
    이미 준비할껀 다 했는뎅 뭘 서운해해?

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2009.03.23 12:07 신고 PERM MOD/DEL

    아 그래??!! 할까 할까? ㅋㅋㅋ

  2. aStRe 2009.03.24 00:00 PERM. MOD/DEL REPLY

    ㅋㅋㅋ if you want you can do everything~!

    Favicon of http://whiteship.me BlogIcon 기선 2009.03.24 10:50 PERM MOD/DEL

    귿~~ My fiancee is generous. Ye~~

    But last night I dreamed about going into bankruptcy. ke ke ke

    show me the money.(You know, this is just a cheat-key in Starcraft.)

  3. aStRe 2009.03.24 10:35 PERM. MOD/DEL REPLY

    ㅡ.ㅡ 작히는 오타쟁이 ㅋㅋㅋ
    piancee = fiancee
    backrupcy= bankruptcy

    Favicon of http://whiteship.me BlogIcon 기선 2009.03.24 10:50 PERM MOD/DEL

    미안 내가 스펠링에 약해ㅋ

Write a comment.


REST in Spring 3: @MVC

Spring/etc : 2009.03.09 11:10


참고: REST in Spring 3: @MVC

스프링 3.0의 RESTful 기능

- URI 템플릿
@PathVariable 애노테이션으로 URI의 특정 위치의 값을 맵핑해올 수 있음.
@RequestMapping("/hotels/{hotelId}")
public String getHotel(@PathVariable hotelId, ModelMap model) {
  List<Hotel> hotels = hotelService.getHotels();
  model.addAttribute("hotels", hotels);
  return "hotels";
}
이때 /hotels/1 이런 요청이 들어오면 hotelId 매개변수로 1이라는 값을 받아올 수 있음.

두 개 이상 맵핑 할 수도 있고 변수명을 다르게 줄 수도 있음.
@RequestMapping(value="/hotels/{hotel}/bookings/{booking}", method=RequestMethod.GET)
public String getBooking(@PathVariable("hotel") long hotelId, @PathVariable("booking") long bookingId, ModelMap model) {
  Hotel hotel = hotelService.getHotel(hotelId);
  Booking booking = hotel.getBooking(bookingId);
  model.addAttribute("booking", booking);
  return "booking";
}

Ant 스타일 경로를 지정할 수도 있음.
@RequestMapping(value="/hotels/*/bookings/{booking}", method=RequestMethod.GET)
public String getBooking(@PathVariable("booking") long bookingId, ModelMap model) {

}

데이터 바인딩도 사용할 수 있음.
@InitBinder
public void initBinder(WebDataBinder binder) {
  binder.initBeanPropertyAccess();
  SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
  dateFormat.setLenient(false);
  binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
}

@RequestMapping("/hotels/{hotel}/dates/{date}")
public void date(@PathVariable("hotel") String hotel, @PathVariable Date date)
                throws IOException {

}
/hotels/1/dates/2008-12-18 이런 요청을 받으면 2008-12-18 이 부분 문자열을 Date 타입으로 바인딩 해 줌.

- Content Negotiation
Accept HTTP 헤더로 뷰를 판단함. 서버 응답은 Content-Type를 통해 뷰를 전달한다. 이런 과정을 content negotiation이라고 한다.

주요 클래스: ContentNegotiatingViewResolver

- Views
RSS 피드를 만들 때 사용할 수 있는 뷰: AbstractAtomFeedView, AbstractRssFeedView
XML 뷰: MarshallingView
JSON 뷰: JacksonJsonView

- HTTP Method Conversion
HTTP에서는 GET, POST, DELETE, PUT을 제공하지만 HTML은 GET, POST만 지원한다. 따라서 POST를 사용하면서 hidden parameter로 Method를 명시하면 해당 Method로 변환해주는 HiddenHttpMethodFilter 제공.
스프링 form 태그에서 이 기능을 지원하기 때문에 form태그의 method에 delete, put도 사용 가능.
<form:form method="delete">
    <p class="submit"><input type="submit" value="Delete Pet"/></p>
</form:form>

@RequestMapping(method = RequestMethod.DELETE)
public String deletePet(@PathVariable int ownerId, @PathVariable int petId) {
    this.clinic.deletePet(petId);
    return "redirect:/owners/" + ownerId;
}

- ETag support
ETga는 HTTP 1.1 호환 응답 헤더로 해당 URL에 있는 컨텐츠가 변경 됐는지 확인할 때 사용.
스프링은 ShallowEtagHeaderFilter를 제공하여 JSP로 랜더링한 결과를 캐싱하고 MD5 해시를 만들고 응답에 ETag를 반환해준다. 다음에도 사용자가 같은 자원을 요청하면 이전에 만든 해시를 If-None-Match 값으로 사용한다. 두 개 해시값을 비교해서 같으면 304(Not Modified)를 반환한다.

차후에 제공할 deep ETag는 모데인 객체나 RDBMS 테이블과 관련되어 있어 좀 더 복잡한데 JPA의 @Version(낙천적-롹킹할 때 사용하는 애노테이션) 기반 또는 ApsectJ의 애스팩트로 지원할 예정~ 이라고 합니다.
top

  1. slgmoney 2009.03.09 12:21 PERM. MOD/DEL REPLY

    제가 궁금해서 그러는데요. 지금 스프링3 m2 버전 .. 이 버전 사용해도 괜찮은건지 궁금합니다. 스프링3가 나올때까지 기다려야 하는건지.. m2 라는것이 완전하진 않지만 사용해도 괜찮다는건지 모르겠네요.. 초보의 질문;; 일단 m이라는게 마일스톤이란 뜻이 맞나요? 그리고 이걸 왜 m2 라고 붙이나요?

    Favicon of http://whiteship.me BlogIcon 기선 2009.03.09 12:46 PERM MOD/DEL

    사용해도 괜찮습니다. 스프링은 충분한 개발자 테스트를 제품과 함께 제공하기 때문이죠.

    마일스톤이라는 뜻 맞구요. m2는 두 번째 마일스톤 버전을 줄여서 표현한 겁니다.

  2. ISU 2010.07.08 19:53 PERM. MOD/DEL REPLY

    안녕하십니까 spring 관련 정보를 많이 얻고 있습니다. 먼저 감사 드리고..
    @PathVariable을 사용하는데 도움을 얻고자 이렇게 문의를 드립니다.

    @RequestMapping(value={"/user/{id}","/user/{id}/book/{cd}"})
    public String home(@PathVariable String id, @PathVariable String cd

    이렇게 처리를 하면 첫번째 url로 접속시 에러가 발생합니다.

    @RequestParam(value = "cd", required = false) String cd

    로 처리를 하면 두번째 url로 접속을 하면 cd가 null로 떨어집니다

    url에 따라 cd도 param으로 받아야 하는데... 가능한 방법이 있을까요?

    Favicon of http://whiteship.me BlogIcon 기선 2010.07.08 23:36 PERM MOD/DEL

    첫번째 질문, URL 두개를 하나의 핸들러에 매핑시켰는데 그 중 첫번째 것으로 접근시 에러나는건 @PathVariable String cd에 바인딩할 부분이 URL에 없어서 그런것 같구요.

    두번째 질문, @RequestParam을 사용한 코드는 URL의 파라미터 부분.. 그러니깐.. member?cd=xxx 이런 부분을 매핑할 때 사용하는 것이지 URI 템플릿을 바인딩 할땐 @PathVariable을 사용하셔야 됩니다. 따라서 요청하신 URL에서 ?cd=xxx 이런 부분이 없기 때문에 null이 들어오는게 아닐까 싶네요.

    말씀하신대로 핸드러를 둘로 나누시는게 좋겠습니다.

  3. ISU 2010.07.08 20:24 PERM. MOD/DEL REPLY

    일단 url별로 두개로 나누고 한쪽에서 return "forward:~" 처리 했습니다.
    혹 더 좋은 솔루션이 있으면 코멘트 부탁드립니다.

    Favicon of http://whiteship.me BlogIcon 기선 2010.07.08 23:38 PERM MOD/DEL

    잘 처리하신것 같네요. forward: 프리픽스를 저럴때 사용할 수 있겠구요. 전 forward:를 잘 안써봐가지고요.ㅋㅋ

  4. ISU 2010.07.09 08:13 PERM. MOD/DEL REPLY

    ^^ 답변 감사드립니다~

    Favicon of http://whiteship.me BlogIcon 기선 2010.07.09 09:59 PERM MOD/DEL

    넵~ 보통은 질문만하고 가지는데 감사인사.. 감사합니다.

Write a comment.


STS(Spring Tool Suite) 2.0 RC 버전의 OSGi 개발 툴

Spring/etc : 2009.03.05 20:29


원문 : OSGi Development Tools in STS 2.0

간단하게 요약만 합니다. 일단 새 제품 다운로드부터 해야겠죠?

기존에 제공하던 툴
  • dm Server Integration: dm 서버를 이클립스 WTP로 통합하여 dm 서버 인스턴스 생명 주기 관리와 OSGi 번들, PAR, 일반 JEE WAR 파일 배포를 할 수 있게 해줌. 또한 dm Server 통합은 설치한 구성물의 코드가 바뀌면 자동으로 업데이트하고 리프레쉬 해줌.
  • 프로젝트 마법사: OSGi 번들과 PAR 프로젝트 생성 마법사 제공.
  • Manifest 편집기와 검증: MANIFEST.MF 파일에서 코드 완성, 하이퍼링크, 검증 기능을 제공.
  • Classpath 관리: OSGi 의존성 메타 데이터를 MANIFEST.MF에서 가져와서 클래스패스 컨테이너를 만든다. 테스트 용 의존성은 테스트 소스 폴더의 META-INF/TEST.MF 사용.
  • 저장소 브라우저: 스프링소스 엔터프라이즈 번들 저장소에 쉽게 접근하게 해준다.
새 기능

STS 2.0은 Import-/Export-Pachage 관계와 서버를 기반으로 번들을 분석하고 그들의 의존성을 가시화하는 기능을 제공한다. OSGi 런타임 콘솔에서 볼 수 있는 텍스트 형태와 비슷한 정보에 접근할 수 있다. 장점은 그런 정보를 IDE에서 쉽게 이요할수 있고 번들 메타 데이터와 연결을 비주얼 툴에서 클릭으로 네비게이션 할 수 있다는 것이다.

서버 편집기에서 Bundle Overview 페이지를 제공한다. 이 페이지에서는 OSGi 런타임에서 접근할 수 있는 모든 연결 정보와 MANIFEST의 번들의 메타 데이터에 접근을 제공하며 설치된 모든 번들을 보여준다.

사용자 삽입 이미지

번들 의존성 그래프를 제공한다. 패키지 또는 서비스 의존성을 보여줄 수 있다. 그래프에서 의존성을 몇 단계까지 보여줄 지 설정할 수 있다.

사용자 삽입 이미지

이퀴녹스 콘솔과 거의 같은 서버 콘솔을 제공한다. 명령 완성과 명령 히스토리 기능을 제공한다.

사용자 삽입 이미지

실행하기

어느덧 다운로드가 끝나고 이제 실행볼 시간이네요. 캬~~ 따끈따끈한 개발 도구를 어디 열어 볼까요~

사용자 삽입 이미지
사용자 삽입 이미지

음~ dm 서버가 잘 들어있군요.  자 일단 서버 만들고 바로 가동시켜 봅니다. 그리고 서버 콘솔에서 ss를 입력해 봤습니다.

사용자 삽입 이미지
다음은 Bundle Information 탭입니다. 와우..

사용자 삽입 이미지
마지막으로 번들 그래프를 보죠.. 캬오~~~~
사용자 삽입 이미지
그림에서 패키지를 더블클릭하면 그래프가 샤샥 바뀌는데 아주 재밌습니다.

이상으로 STS 2.0 리뷰를 마칩니다.
top

  1. Favicon of https://helols.tistory.com BlogIcon is윤군 2009.03.05 20:50 신고 PERM. MOD/DEL REPLY

    홋;; 빨라 빨라 ~~ ~~ ㅋ
    전 Groovy 1.6 보면서 후덜덜덜 .. 이러고 있는데;;ㅋ
    굳 ! 맨 !

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2009.03.05 21:20 신고 PERM MOD/DEL

    ㅇㅇ그루비 나도 봐야지~

Write a comment.


스프링 3.0 m2 빌드 삽질 중

Spring/etc : 2009.03.04 02:21


http://blog.springsource.com/2009/03/03/building-spring-3/ 윗 글을 보며 삽질 중입니다.

사용자 삽입 이미지

컴파일 에러가 난다며 두 번째 단계에서 막히네요. 자바 1.5라서 그런가 싶어서 kenu 형 블로그보고 1.6으로 바꾼 담에 해봤지만... 그래도 안 되네요. 흠~ 왜 컴파일이 안 되는걸까나.. @_@

readme.txt를 읽어봤더니 javac 1.6 이상, ant 1.7 이상이라길래 다시 한 번 버전을 확인해 봤습니다
사용자 삽입 이미지
흠~~ @_@ 두 시가 넘었네.. 낼 다시 해보자.


top

  1. Favicon of http://toby.epril.com BlogIcon 토비 2009.03.04 07:26 PERM. MOD/DEL REPLY

    바보

    Favicon of http://whiteship.me BlogIcon 기선 2009.03.04 10:41 PERM MOD/DEL

    그런가봐요. 흑...

  2. Favicon of https://helols.tistory.com BlogIcon is윤군 2009.03.04 09:27 신고 PERM. MOD/DEL REPLY

    나도 어제 새벽에 블로그 올라 왔길래 해봣는데;; 자바 1.6.10버전으로 했구 ant 1.7.1 버전.. ;; 컴파일 하는데는 오류는 안났지만.. ant 실행시 outofmemory 가 나서 .. ㅋ 시간이 좀 걸렸다는;;
    블로그에 보면;; 빌드를 위해선 java6 버전이 필요하다고 나와 있잖아요 ;;ㅋ
    한번 다하고 다시 한번 다했는데;; 40분 15초 걸리던데요;; ㅡㅡ; 새벽 3시까지 돌렸다는거;; ㅜ

    Favicon of http://whiteship.me BlogIcon 기선 2009.03.04 10:41 PERM MOD/DEL

    염장이지?! 난 컴파일이 안 된다고! ㅠ.ㅠ

Write a comment.


Petclinic을 통해 스프링 3.0 주요기능 살펴보기

Spring/etc : 2009.02.26 10:09


Spring Framework 3.0 M2 released

스프링 3.0 m2가 배포됐습니다. 유겐 휄러가 주요 기능을 잘 정리해 뒀네요. 아쉬운건 아직도 레퍼런스 업데이트가 되지 않았다는 겁니다. 어쩔 수 없이 아쉬운 사람이 우물 판다고 예제 코드를 뒤적거릴 수밖에 없더군요.

EL 지원에 관한 예제는 petclinic-servlet.xml에서 볼 수 있습니다.

    <bean id="visits" class="org.springframework.samples.petclinic.web.VisitsAtomView"/>

    <bean id="vets" class="org.springframework.web.servlet.view.xml.MarshallingView">
        <property name="contentType" value="application/vnd.springsource.samples.petclinic+xml"/>
        <property name="marshaller" ref="marshaller"/>
    </bean>

    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        <property name="mediaTypes">
            <map>
                <entry key="xml" value="#{vets.contentType}"/>
                <entry key="atom" value="#{visits.contentType}"/>
            </map>
        </property>
        <property name="order" value="0"/>
    </bean>

이렇게 visits와 vets 빈의 contentType 속성에 들어있는 값을 #{vets.contentType}, #{visits.contentType} 이런식으로 참조하여 다른 빈에 주입할수 있습니다. visits에는 contentType속성이 없는 것 같지만 이 속성은 AbstractView에 있는 속성이고 VisitsAtomView 클래스가 그것을 상속했기 때문에 기본값을 가지게 될 겁니다.

다음으로 RestTemplate 기능은 컨트롤러에서 볼 수 있습니다.

@Controller
@RequestMapping("/owners/{ownerId}/pets/new")
@SessionAttributes("pet")
public class AddPetForm {
...
    @RequestMapping(method = RequestMethod.GET)
    public String setupForm(@PathVariable("ownerId") int ownerId, Model model) {
        Owner owner = this.clinic.loadOwner(ownerId);
        Pet pet = new Pet();
        owner.addPet(pet);
        model.addAttribute("pet", pet);
        return "pets/form";
    }
...
}

이런 식으로 URL의 일부를 매서드 매개변수로 바인딩 해줍니다. 바인딩 할 필요가 없는 경우 와일드 카드를 이용할 수도 있습니다.

@Controller
@RequestMapping("/owners/*/pets/{petId}/visits/new")
@SessionAttributes("visit")
public class AddVisitForm {
...
    @RequestMapping(method = RequestMethod.GET)
    public String setupForm(@PathVariable("petId") int petId, Model model) {
        Pet pet = this.clinic.loadPet(petId);
        Visit visit = new Visit();
        pet.addVisit(visit);
        model.addAttribute("visit", visit);
        return "pets/visitForm";
    }
...
}

이런 식으로 말이죠. 간단해 보이네요~

다음으로는 AtomView 지원 기능도 살펴봤습니다. 3.0에 추가된 AbstractAtomFeedView 이 클래스를 상속해서 구현하면 되더군요.

public class VisitsAtomView extends AbstractAtomFeedView {
...
    @Override
    protected void buildFeedMetadata(Map<String, Object> model, Feed feed, HttpServletRequest request) {
...
    }

    @Override
    protected List<Entry> buildFeedEntries(Map<String, Object> model,
            HttpServletRequest request, HttpServletResponse response) throws Exception {
...
    }
   
}

구현은 이런 식이며 피드 메타 데이터는 Feed 객체에 Id와 Title을 그리고 Updated에 날짜를 채워줍니다. 코드에 에러가 있어서 Feed 라는 클래스를 자세히 보지 못해서 아쉽네요. 그 아래 매서드에서는 Entry List를 만들어서 반환해줍니다. Entry도 역시 자세히 보고 싶은데 못봤습니다. id, title, updated, summary 정보를 설정하는 코드로 대충 어떤 속성이 있는지 예상할 순 있었습니다.

마지막으로 OXM 기능을 살펴봤는데 끝내주더군요. @_@

    <bean id="vets" class="org.springframework.web.servlet.view.xml.MarshallingView">
        <property name="contentType" value="application/vnd.springsource.samples.petclinic+xml"/>
        <property name="marshaller" ref="marshaller"/>
    </bean>

    <oxm:jaxb2-marshaller id="marshaller">
        <oxm:class-to-be-bound name="org.springframework.samples.petclinic.Vets"/>
    </oxm:jaxb2-marshaller>

보시다시피 MarshallingView는 스프링 3.0에서 제공하는 클래스고 Vets는 도메인 클래스입니다. OXM을 지원하는 스키마까지 제공하는군요. 저렇게만 설정하면 객체를 알아서 XML로 변환해주느냐???... 아니요 한가지 더 필요합니다.

 @XmlRootElement
public class Vets {

    private List<Vet> vets;

    @XmlElement
    public List<Vet> getVetList() {
        if (vets == null) {
            vets = new ArrayList<Vet>();
        }
        return vets;
    }

}

캬... 뭐 대충 눈으로 보면 뭐하는건지 알 수 있게해주는 직관적인 코드입니다.

자 이정도면 대충 주요 기능은 거의다 조금 살펴본 것 같습니다. 예제 코드좀 돌려보면 좋겠는데 그건 나중에 해봐야겠습니다. 지금은 번역 땜시..-_-;;



top

  1. Favicon of https://helols.tistory.com BlogIcon is윤군 2009.02.26 13:18 신고 PERM. MOD/DEL REPLY

    큭; OXM 멋찐데요;;ㅋ 확 땡기는데 3.0이요;ㅋ

    Favicon of http://whiteship.me BlogIcon 기선 2009.02.27 09:16 PERM MOD/DEL

    ㅇㅇ 귿이네~
    역시 스프링소스야

  2. 권남 2009.02.26 18:12 PERM. MOD/DEL REPLY

    잘봤습니다~
    3.0을 확질러버려... ^^

    Favicon of http://whiteship.me BlogIcon 기선 2009.02.27 09:17 PERM MOD/DEL

    ㅋㅋ2.5부터 마무리 하구요.

  3. Favicon of http://igooo,org/tc BlogIcon igooo 2009.02.27 10:04 PERM. MOD/DEL REPLY

    [질문]예제는 어디에서 볼 수 있나요?

    Favicon of http://whiteship.me BlogIcon 기선 2009.02.27 11:01 PERM MOD/DEL

    스프링 3.0 m2 소스코드를 다운 받으시면 볼 수 있습니다.

Write a comment.


스프링 트랜잭션 주의할 것

Spring/etc : 2009.02.07 20:46


Transaction strategies: Understanding transaction pitfalls

@Transactional(readOnly = true, propagation=Propagation.REQUIRED)
public long insertTrade(TradeData trade) throws Exception {
   // 어떤 코드
}

위 코드에 있는 insertTrade를 실행행하면 어떤 결과가 발생할까요?

A. read-only connection 예외가 발생한다.
B. 데이터를 추가하고 커밋한다.
C. read-only가 true라서 아무것도 하지 않는다.

당연히 A일 것 같은데... // 어떤 코드 부분이 JDBC 코드일 경우이고 JPA나 하이버네이트 같은 ORM 코드면 propagation 설정 REQUIRED가 모든 것을 재정의해서 새로운 트랜잭션을 시작하고 read-only 플래그가 없는 것 처럼 동작하게 된다네요... @_@

지금은 넘 졸려서 낼 자세히 읽어봐야겠습니다.

따라서 읽기 전용 매서드의 경우 다음과 같이 SUPPORTS 프로퍼게이션 모드를 사용하는게 타당하다고 합니다. 왜냐면 보통 다음과 같이 읽기 전용 매서드를 설정하는데..

@Transactional(readOnly = true)
public TradeData getTrade(long tradeId) throws Exception {
   return em.find(TradeData.class, tradeId);
}

이 때 기본 프로퍼게이션이 REQUIRED 모드기 때문에 매번 새로운 트랜잭션을 만들어 사용하고 사용하는 DB에 따라서는 불필요한 읽기 롹까지 사용해서 데드락을 발생시킬 수도 있다고 하기 때문입니다. 따라서..

@Transactional(readOnly = true, propagation=Propagation.SUPPORTS)
public TradeData getTrade(long tradeId) throws Exception {
   return em.find(TradeData.class, tradeId);
}

이렇게 SUPPORTS로 변경하여 기존 트랜잭션이 있으면 사용하고 없으면 사용하지 않도록 하거나..

public TradeData getTrade(long tradeId) throws Exception {
   return em.find(TradeData.class, tradeId);
}

요렇게 읽기 전용인 경우에는 아예 @Transactional 애노테이션을 아예 사용하지 않는게 나아보입니다. 굳이 원자화 할 것도 없고~ Isolation level만 적당선에서 타협한다면 롹을 걸 일도 없고~


REQUIRES_NEW  사용시 주의 할 것.

@Transactional(propagation=Propagation.REQUIRES_NEW)
public long insertTrade(TradeData trade) throws Exception {...}

@Transactional(propagation=Propagation.REQUIRES_NEW)
public void updateAcct(TradeData trade) throws Exception {...}

이런 매서드와 트랜잭션 설정이 있을 때

@Transactional(propagation=Propagation.REQUIRES_NEW)
public long insertTrade(TradeData trade) throws Exception {
   em.persist(trade);
   updateAcct(trade);
   //exception occurs here! Trade rolled back but account update is not!
   ...
}

이런 식으로 코딩하면... updateAcct() 이후에 에러가 발생하면 updateAcct는 쿼리가 날아가는데 나머지 내용은 롤백 되는 현상이 발생할 수 있죠. 왜냐면 매번 새로운 트랜잭션을 만들기 때문에 insertTrade를 실행하는 트랜잭션과 updateAcct를 실행하는 트랜잭션이 별개기 때문입니다.

뭐~ 이건 쉽네요. 걍 REQUIRED로 쓰거나 MANDATORY를 쓰면 됩니다.

롤백과 관련해서는 checked exception에 대비해야 한다.

@Transactional(propagation=Propagation.REQUIRED)
public TradeData placeTrade(TradeData trade) throws Exception {
   try {
      insertTrade(trade);
      updateAcct(trade);
      return trade;
   } catch (Exception up) {
      //log the error
      throw up;
   }
}

이런 코드가 과연 안전할까? 아니요. 왜냐면 저 코드에서 만약 updateAcct() 매서드 처리 도중에  checked exception이 발생하면 insertTrade() 매서드는 그대로 실행하고 예외도 그냥 던지고 말기 때문에 데이터가 불안전한 상태가 될 것입니다. 따라서 checked exception에 대비해서..

@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
public TradeData placeTrade(TradeData trade) throws Exception {
   try {
      insertTrade(trade);
      updateAcct(trade);
      return trade;
   } catch (Exception up) {
      //log the error
      throw up;
   }
}

이런 식으로 하는게 좋겠습니다.



top

  1. 권남 2009.03.09 16:19 PERM. MOD/DEL REPLY

    Spring 2.5, Hibernate 3.3, @Transactional(readOnly = true, propagation=Propagation.REQUIRED) 이 상태에서 insert를 할경우, 왜 난 readOnly니까 쓰기 작업을 할 수 없다는 오류가 날까요?
    원문을 봐도 마찬가지던데.. 내가 뭔가를 잘못이해하고 있나봐요.

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2009.03.09 16:48 신고 PERM MOD/DEL

    그 매서드 안에 코드는 하이버네이트 Session을 사용하신거겠죠?

    음.. 아마도 트랜잭션을 저 매서드를 만날 때 새로 만든게 아니라 기존에 있던 트랜잭션을 사용하는거라 그렇게 잘 동작한게 아닐까 싶네요.

    OSIV 필터 같은 것을 쓰신다면 요청이 들어왔을 때 쓰레드로컬에 미리 만들어 두니까요.

  2. Favicon of http://kwon37xi.egloos.com BlogIcon 권남 2009.03.09 20:14 PERM. MOD/DEL REPLY

    -- 수정: 이 댓글은 오류를 포함하고 있습니다.

    문제점을 확인하였습니다.
    문서를 자세히 보면

    For some vendors, such as Hibernate, the flush mode will be set to MANUAL, and no insert will occur for inserts with non-generated keys

    이 부분이 있는데, 이런 현상은 non-generated key(auto_increment를 사용하지 않고, 키 값이 객체에 직접 지정되는 방식)이고, Flush 모드가 Manual(기본 모드죠?) 이면서, insert/update 등을 할 때 발생합니다.
    내생각엔 generated key 일 경우일지라도, 시퀀스를 사용해서 키를 생성하는 DB에서는 insert가 될 것으로 보입니다. sequence에서 키값 가져오는 것은 read 작업이라서 그냥 해버리고 말 수도 있으니까(이건 단순 가정임).

    그 경우, 트랜잭션 안에서 insert가 일어나지 않고, 스프링의 트랜잭션 영역을 빠져 나간뒤에 한꺼번에 insert가 일어나기 때문에 스프링의 트랜잭션 설정의 영향을 받지 않게 됩니다.

    실제로 트랜잭션 종료 직후 시점에서 로그를 찍어보니, 트랜잭션이 종료된 이후에 insert statement가 실행되었습니다.

    아무때나 이런 현상이 일어나는 것은 아니었던 것이죠.

  3. Favicon of http://kwon37xi.egloos.com BlogIcon 권남 2009.03.09 20:16 PERM. MOD/DEL REPLY

    위 세번째 댓글은 저의 착각이었습니다. 다른 readOnly=false 트랜잭션이 걸린 서비스로 감싼 상태에서 안쪽 서비스 메소드의 readOnly=true 만 보고서 읽기 전용에서 호출했다고 착각했네요.

    제가 찾은 결론은, 위와 같은 readOnly=true 상태에서, insert,update 되는 현상은 나타나지 않는 다는 것입니다.

    스프링의 hibernateTemplate을 통해 save 메소드를 타게 되면 스프링 내부에서 checkWriteOperationAllowed(session) 메소드로 무조건 트랜잭션이 writable한지 여부를 검사합니다.
    따라서 HibernateTemplate을 사용하면 위 문서에서 말한 현상은 발생할 수 없습니다.
    update,delete도 마찬가지더군요.

    하지만 예외적으로, Spring HibernateTemplate을 사용하지 않고, Hibernate Session의 save 메소드를 직접 호출하면 readOnly=true인데 insert/update가 되는 현상이 발생합니다.
    트랜잭션의 writable 여부를 체크하는 것은 스프링이지 하이버네이트가 아니기 때문입니다. 스프링을 거치지 않고 Hibernate의 메소드를 바로 호출하면, 원문에 나온 트랜잭션의 writable여부와 무관하게 save되는 오류가 발생하게 됩니다.(그것도 non-generated id를 가진 엔티티의 경우에 한합니다).

    Favicon of http://whiteship.tistory.com BlogIcon 기선 2009.03.09 20:43 PERM MOD/DEL

    넹 위 본문에서도 스프링의 템플릿 클래스들이 아니라 JPA의 EntityManager나 하이버네이트의 Session을 사용할 때 발생할 수 있는 문제를 말해준 듯 합니다.

    저는 스프링의 템플릿 클래스들을 사용하지 않고 하이버네이트 API를 직접 이용해서 DAO를 구현하는게 더 깔끔해서 그렇게 사용하고 있습니다.

    따라서 결론을 약간 보완하여.. 스프링의 XXXTemplate 클래스를 사용하면 readOnly=true 상태에서 insert, update되는 현상은 나타나지 않는다. 라고 하는게 좋을 듯해 보이네요. ^^

  4. 권남 2009.03.09 23:53 PERM. MOD/DEL REPLY

    내가 HibernateTemplate 쓴다고 남들도 다 그렇겠거니 하는 생각에, EntityManager 를 못봤군요. --;
    암턴 올만에 소스 뒤져봤어요.. ^^

    Favicon of http://whiteship.me BlogIcon 기선 2009.03.10 09:52 PERM MOD/DEL

    캬~~ 멋지세요.
    하이버네이트 번역도 같이 하실래요. ㅋㅋ

Write a comment.


빈 속성에 값 설정 했는지 확인하기

Spring/etc : 2009.02.04 21:22


null 체크가 될 수도 있겠고 어떤 값이든 주입 됐는지 확인하는 것일 수도 있겠습니다. 예전에 대충 정리해둔 적은 있는데 잊어버렸던 거라서 다시 정리해 둡니다.

<bean> 엘리먼트에 dependency-check라는 속성이 이 속성을 설정하지 않으면(기본값) 빈 속성에 어떤 값이나 빈이 주입 되었는지 확인하지 않습니다.

simple 값을 주면 기본 타입과 컬렉션 타입만 검사합니다.

object 값을 주면 simple이 검사하는 것을 제외한 레퍼런스 타입을 검사합니다.

all 값을 주면 모든 속성을 검사합니다.

요즘은 @Autowired로 주로 DI를 하기 때문에 점점 예전 빈 설정 내용들은 잊혀져 가는 것 같습니다. @Autowired는 기본 값이 필수로 되어있죠. 그래서 오히려 반대로 없어도 괜찮다고 설정 하려면 애노테이션에 required=false 속성을 추가해 줘야 합니다.

...
    private MovieFinder movieFinder;

    @Autowired(required=false)
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }
...

이런 식으로..
top

Write a comment.


싱글톤, 비싱글톤 언제 써야 할까?

Spring/etc : 2009.02.04 21:10


참고:  Pro Spring 2.5 3장

요즘 이 책을 재벌 작업을 하고 있는데 공부한지 오래되서 잊었거나 미쳐 보지 못했던 내용들이 등장하면 피로가 조금 줄어드는 느낌을 받곤 합니다.

그 중 하나가 바로 이 글의 제목과 관련된 내용이었습니다. 스프링을 가지고 웹 애플리케이션을 몇 번 만들어 봤지만 singleton 스코프 빼곤 별로 써본 기억이 나질 않을 정도인데 새삼 생각해보게 하는 내용들이 있었습니다.

싱글톤이 적절한 경우
- 상태가 없는 공유 객체
- 읽기 전용 상태를 가지고 있는 공유 객체
- 상태를 공유하는 공유 객체
- 쓰기가 가능한 상태를 약간 가지고 있으면서 매우 빈번하게 사용하는 객체

비싱글톤이 적절한 경우
- 쓰기가 가능한 상태를 가진 객체
- private 상태를 가지고 있는 객체

여기서 주목해야 할 것은 같은 쓰기 가능한 상태를 가진 객체인데 어느것은 싱글톤 어느 것은 비싱글톤이 적절하다는 부분인데 동기화 비용과 객체 생성 비용을 가지고 나누더군요.

자세한 내용은 프로 스프링 2.5 번역서를 참고하세요~ ㅋㅋㅋ
top

  1. Favicon of https://helols.tistory.com BlogIcon is윤군 2009.02.04 23:31 신고 PERM. MOD/DEL REPLY

    글만 봐선 딱히 잘 모르겠네욥..ㅋ
    어여 빨리 3장 궈궈쓍~;;

    Favicon of http://whiteship.me BlogIcon 기선 2009.02.05 09:19 PERM MOD/DEL

    오늘 베타리딩에 올린다~

  2. 신난다 2009.02.05 01:17 PERM. MOD/DEL REPLY

    싱글턴은 장점보다 단점이 훨씬 큰데,
    싱글턴을 쓰지 말자는게 아니라
    적절한 경우를 나열한 책이 있다니 사실에 움찔했습니다.

    적절하다고 예로든 경우에도 MonoState 패턴이 더 적절하다고 생각합니다.

    Favicon of http://whiteship.me BlogIcon 기선 2009.02.05 09:19 PERM MOD/DEL

    넹.. 글쿤요!

    토비 2009.02.05 13:26 PERM MOD/DEL

    스프링의 싱글톤 스코프와 디자인패턴에서 말하는 싱글톤 패턴을 같은 것이라고 오해하신 것 같군요.
    스프링은 기존 싱글톤 패턴의 문제를 극복하기 위해서 싱글론 레지스트리라는 방식으로 싱글톤 개념을 적용합니다. 이를 이용하면 싱글톤 패턴과 같은 방식을 사용하지 않은 단순한 자바 클래스를 싱글톤 "개념"으로 사용할 수 있습니다.

    Favicon of http://whiteship.me BlogIcon 기선 2009.02.05 14:13 PERM MOD/DEL

    싱글톤 패턴의 문제라 함은?
    - 인터페이스를 사용하지 못 함.
    - 구현체 교체하기 힘듬
    - 따라서 테스트 하기도 힘듬.
    이런 것일듯..

    Kevin 2009.03.02 01:28 PERM MOD/DEL

    싱글톤도 인터페이스 사용할 수 있습니다.
    그러니 구현체 교체도 힘들지 않구요.

    다만 싱글톤 자체를 상속하여
    Subtyping 하는것에 문제가 생겨서
    재사용성과 확장성을 보장하기 힘들다는것이
    문제가 아닐까 싶습니다.

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2009.03.02 09:20 신고 PERM MOD/DEL

    넹.. 찾아보니 조금 복잡해 보이지만 Singleton Interface를 사용하는 방법도 있었네요.

    http://radio.weblogs.com/0122027/stories/2003/10/20/implementingTheSingletonPatternInJava.html

    감사합니다~

  3. 신난다 2009.02.05 15:28 PERM. MOD/DEL REPLY

    오~ 알겠습니다.
    움찔하지 않아도 되서 다행이네요. ^^

Write a comment.


DI(Dependency Injection)의 장점

Spring/etc : 2009.01.21 14:27


참조: 프로 스프링 2.5 1장

접착 코드(glue code) 감소
- JNDI를 사용할 경우 복잡해질 수 있느 코드를 DI로 대체하면 깔끔해진다.

의존성 외부화
- 설정 옵션 분리, 의존성 변경 용이함

한 곳에서 의존성 관리
- 각각의 클래스 내부에서 자신의 의존성을 관리하는 것 보단 한 곳에서 관리하는 것이 편리함

테스트 편의성 향상
- 테스트용 더비(Dummy) 구현체로 쉽게 교체할 수 있기 때문에 귿.

좋은 애플리케이션 설계 도출
- DI를 활용하다보면 컴포넌트를 인터페이스를 사용하여 연결하게 된다. 이러한 설계야 스프링 전에도 가능했지만 스프링이 알아서 다 해주는걸 무료로 사용할 수 있으니까 비즈니스 로직에만 집중할 수 있을 것이다.


ps1: 프로 스프링 1장 베타리딩 시작합니다.
ps2: 베타리딩은 봄싹에서 전담합니다.
top

Write a comment.


스프링과 디자인 패턴

Spring/etc : 2009.01.16 10:22


참조, 요약: 프로 스프링 2.5

인터페이스 기반 프로그래밍
생성 패턴
- Singleton: BeanFactory
- Factory
- Builder: BeanDefinitionBuilder
- Prototype: 스프링 없이 만들려면 별도의 추상 클래스 만들고 makeCopy() 같은 매서드 필요해
구조 패턴
- Proxy: 스프링 AOP
- Adapter: MessageListenerAdapter, MessageListenerAdapter102(어댑터), MessageListener
- Wrapper와 Decorator: DisplayTag
- Facade
행동 패턴
- Observer: ApplicationListener
- Strategy
템플릿 매서드
- JdbcTemplate, HibernateTemplate, HibernateCallback, ...

흠~ 여기서 좀 걸리는건 템플릿 매서드 패턴의 예로 든 JdbcTemplate 및 기타 Template 들인데요. 빨간책에서는 템플릿 매서드 패턴으로 XXSqlQuery 클래스들을 꼽고 있고 XXTemplate들은 Stategy 패턴의 일종인 콜백이라고 하고 있는데 좀 혼란을 주네요. @_@
top

  1. 토비 2009.01.16 15:02 PERM. MOD/DEL REPLY

    자세히 보면 좀 달라

    Favicon of http://whiteship.tistory.com BlogIcon 기선 2009.01.18 21:03 PERM MOD/DEL

    넹.. KSUG 포럼에서 한 참 논의했던 내용인지라 눈에 확 띄더라구요.

Write a comment.


그루비 사용자와 스프링

Spring/etc : 2009.01.07 10:55


스프링의 동적 언어 지원 기능은 2.0 버전부터 두각을 드러냈지만 '아.. 이런 기능이 있네..' '오.. 되는구나..' 정도로 간단한 예제를 몇 개 실험해봤을 뿐 어떻게 활용해야 할지는 전혀 몰랐는데 관련 기사가 developerWorks에 떴습니다. 두 개씩이나..

Groovier Spring, Part 1: Integration basics

Groovier Spring, Part 2: Change application behavior at run time

1부는 2월에 2부는 3월에 번역해서 한국 IBM developerWorks에 올릴 생각입니다.
top

  1. Favicon of http://ryudaewan.tistory.com BlogIcon 하얀말 2009.01.14 14:45 PERM. MOD/DEL REPLY

    안그래도 저 문서 읽어볼래다 영어라 귀차니즘 발동했었는데 ㅋㅋ, 번역 기대합지요.

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2009.01.14 22:57 신고 PERM MOD/DEL

    넵 일정이 좀 늦어져서 3, 4월에 올라올 것 같네요.

Write a comment.


드디어 한국에서도 SpringSource에서 직접 교육을 하네요.

Spring/etc : 2009.01.05 13:19


아침에 사부님께서 링크를 줘서 들어가봤다가 깜짝 놀랬습니다.

http://www.springsource.com/training/spr001/icn20090302

한국에서 3월 2~5일까지 4일 과정으로 스프링 Core 교육을 합니다.
교육비는 호주 달러로 약 3000달러.. 현재 환율로 280만원 정도.

또 하나의 거대한 지름신이 유혹을 하네요. 저 떄 한국에 있을지 없을지도 모르는데 질러야 하나 말아햐 하나 고민입니다.

교육에 대한 자세한 설명은

http://www.springsource.com/training/spr001/syllabus

여기에 있습니다. 재밌는 건 Assumptions 인데..

We assume participants have a good understanding of the core Java APIs, as well as a basic knowledge of general J2EE concepts and APIs such as JTA and the Servlet API. As we cover object-relational mapping technologies (ORM) in this course as well, we assume basic knowledge of ORM concepts.

자바와 JEE 개념을 그렇다치고 ORM 기본 개념이 필요하다는 것 있다는 것과..
교육 과정 설명 중에 Hibernate란 단어가 대 여섯 번 정도 포함되어 있다는 것입니다.
그래서 인지 더욱 끌리네요~

Analysis and tradeoffs of relevant persistence strategies, including Hibernate and Spring JDBC
...
Understanding ORM and Hibernate with Spring
...

top

  1. Favicon of http://yunsunghan.tistory.com BlogIcon Max 2009.01.05 17:01 PERM. MOD/DEL REPLY

    역시 비싸군요....
    한국에서 얼마나 신청할지도 의문이지만,
    실습형태의 교육이 예상되는군요.

    영어 듣기만으로는 버티기 힘들지도 모르겠지만,
    모험심 있는 분들은 절호의 찬스 일수도 있겠네요...

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2009.01.05 20:16 신고 PERM MOD/DEL

    네. 개인이 지불하기에는 좀.. 비싸네요.

  2. Favicon of https://lostsin.tistory.com BlogIcon 시난 2009.01.06 10:49 신고 PERM. MOD/DEL REPLY

    가끔 들리는 개발자인데.. 스프링 달인아니세요? ㅎㅎ
    이런 교육들을 들을 필요가 있으신가요? 없으실 것 같은데 ^^;

    Favicon of http://whiteship.me BlogIcon 기선 2009.01.06 11:08 PERM MOD/DEL

    저는 초보에요;; 그냥 조금 쓸 줄만 아는 정도랍니다.

    아무래도 스프링소스 직원이 갈쳐주는 교육이라 뭔가 색다른 것이 있겠죠?

Write a comment.


뢉 해럽 쌩큐

Spring/etc : 2008.12.12 15:01


참조: http://blog.springsource.com/2008/12/11/slides-and-demos-from-springone-americas-2008/

뢉 해럽이 S1A에서 발표한 세션 중 두 개 세션의 ppt와 소스 코드를 공개했습니다.

그 중 하나가 컨커런시인데 이 부분은 굳이 스프링 애호가나 사용자가 아니여도 들어볼 만한 세션인 것 같습니다. 코딩을 얼마 해보지도 않았지만, 컨커런시를 다룬 코딩은 정말 조금 밖에 안 해봤고(배치와 스케줄러 관련 작업할 때 조금 해본 기억이 나네요. 아주 조금; 단순하거.. 그것도 사부님한테 여러번 수정 사항 지적받으면서..) 별로 궁금하지도 않았습니다. Thread랑 Runnable 가지고 깨우고 재우고 롹킹하고 어쩌구 저쩌고.. 정도만 알고 있었을 뿐..

이번 뢉 해럽의 발표를 보니까 정말 정말 많은 기능들이 자바에 추가되고 있었습니다. 몰랐습니다. 거의 90% 가까이 내용을 못 알아들었습니다. 좌절했죠. (역시 아는 만큼만 보이고 들리더군요.) 그래서 돌아가면 소스 코드 보면서 다시 공부하리라 마음 먹었습니다. 뢉 해럽한테 가서 소스 코드도 얻어보려고 발표가 끝나고 앞에 나가서 "how can I get the source code? example source code." 라고 질문도 했었죠.ㅋㅋ 그랬더니 오늘쯤 블로그에 올린다고 하더니 정말 올려줬습니다.

S1A에 가서 첫날 뢉 해럽한테 우루루 몰려가서 사진찍고 둘 쨋날은 맨 앞에서 뢉 해렵의 모든 세션(dm 서버 관련 3개)에 참석하고 마지막 날은 사인까지 받았고 질문도 했으니.. 다음에 찾아가도 절 기억해 주겠죠? 기억 못하면 다시 사진 한 방.. ㅋㅋ
top

  1. Favicon of http://yunsunghan.tistory.com BlogIcon Max 2008.12.13 10:04 PERM. MOD/DEL REPLY

    Rob Harrop 이양반 얼굴 사진으로 보면... 외계소년 위제트 닮았어요~ :)
    사진비교 : http://files.youngsamsung.com/uploads/campus/editor/make_1216643706186.JPG

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2008.12.13 20:37 신고 PERM MOD/DEL

    ㅋㅋㅋ맞아요 정말 비슷하네요.

Write a comment.


Spring by Example

Spring/etc : 2008.12.12 14:49


참조: http://www.springbyexample.org/

스프링을 사용하는 여러 코드를 정리해 두었습니다. 주로 한 사람(David)이 코드를 올렸고 간간히 다른 사람의 이름도 보입니다. 레퍼런스 스타일로 쉽게 참조해서 스프링을 사용해 볼 수 있겠습니다. 재밌는 활동인 것 같은데 기회가 되면 저도 참여해야겠습니다. 저런 사이트가 관리가 잘 되고 규모가 커져서 다양한 시나리오와 그 시나리오에 적절한 코드 사용법까지 정리된다면 굉장한 스프링 관련 사이트가 될 것 같습니다.
top

  1. Favicon of http://yunsunghan.tistory.com BlogIcon Max 2008.12.13 09:56 PERM. MOD/DEL REPLY

    재밌는 것은 단순히 예제만 있는것이 아니라, 불편한 것은 직접 확장하여 편리한 클래스까지 제공하기도 한다는 겁니다. (http://yunsunghan.tistory.com/259 참조) ^^*

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2008.12.13 20:37 신고 PERM MOD/DEL

    오호 그랬군요.

Write a comment.


스프링 프레임워크 3.0 M1 배포~

Spring/etc : 2008.12.08 22:19


참조: http://blog.springsource.com/2008/12/05/spring-framework-30-m1-released/
  • revised project layout and build system with module-based sources
  • updated entire codebase for Java 5 code style (generics, varargs)
  • updated to JUnit 4.5 and JRuby 1.1
  • introduced Spring EL parser (org.springframework.expression package)
  • introduced support for #{…} expressions in bean definitions
  • introduced expression-enabled @Value annotation for embedded expressions
  • introduced @PathVariable annotation for URI template handling in MVC handlers
  • introduced default value support for @RequestParam in MVC handlers
  • introduced @RequestHeader annotation for HTTP header access in MVC handlers
  • introduced AbstractAtomFeedView and AbstractRssFeedView base classes
  • introduced <spring:url> and <spring:param> JSP tags

오늘 발표 됐습니다. 소스 코드 저장소가 SVN으로 바꼈고 구조도 바꼈습니다. spring.jar는 더이상 관리하지 않기 때문인지 전부 세부 프로젝트로 바꼈네요. 소스 코드를 받아봐야겠습니다.

엄청 기능 추가가 있는데 바로 EL 기능 추가 입니다. 이걸 XML 이나 애노테이션 속성 값 부분에 사용해서 특정 value또는 메소드를 실행한 결과 값을 설정할 수 있습니다.

또 웹 쪽에도 중요 기능이 추가됐습니다. @PathVariable을 사용해서 REST 스타일의 URL 템플릿을 사용할 수 있습니다. 또한 @RequestHeader를 이용해서 헤더 정보에 바로 접근할 수 있습니다. 굳이 HttpServletRequest변수를 사용해서 꺼내는 코드를 작성하여 Servlet API에 의존하지 않아도 된다는 겁니다. 나중엔 쿠키나 세션도 지원해줄 것 같습니다. RSS 뷰도 주 개가 추가되었습니다. JSON 뷰는 보이지 않는 군요. 그것도 추가해준댔는데.. 그리고 jsp 태그 두 개가 추가됐습니다. 뭔지는 잘 몰겠습니다.


top

Write a comment.


로드 존슨과 친구들이 싸인한 스프링 책이 나에게 주는 의미

Spring/etc : 2008.12.04 14:15



Pro Spring 저자 뢉 해럽 한테도 받았습니다. 아레프 앤더슨은 안 보여서 못 받고, 로드 존슨, 유겐 휄러, 토마스, 콜린 한테도 받았습니다. 이전 글에서도 언급했지만, 다음에는 이들과 대화를 하지 못 할 거라면 아예 가지 않겠습니다.

고로.. 저에게 저 싸인들은 '가서 엄마 젓 좀 더 먹고와...'(->영어 제대로 익혀서 와) 라는 의미입니다. 좀 더 선명하게 찍어서 출력하고 매일 보면서 각성 해야겠습니다.

저는 정말 감흥으로 끝내고 싶지 않습니다. 소통하고 싶습니다.
top

  1. Favicon of http://helols.tistory.com BlogIcon 성윤 2008.12.04 14:49 PERM. MOD/DEL REPLY

    헛;; 이것도 대박;; ㅜㅜ

    즐거운 나날들이겠어요;;^^;; ㅋ

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2008.12.05 12:39 신고 PERM MOD/DEL

    넹 경치도 좋고... 이 보다 더 염장 사진들도 있는데요. 올릴까 말까 고민입니다.

    비행기에서 내려다 경치.. 아침에 해 뜨는 거.. 해 지는 저녁 노을.. 시원한 수정장.. @.@

    감상에 빠질 시간이 없어서 못 올립니다.

  2. Favicon of http://sunnykwak.egloos.com BlogIcon 써니 2008.12.04 15:00 PERM. MOD/DEL REPLY

    으헉.. 이건 너무 큰 염장입니다!

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2008.12.05 12:40 신고 PERM MOD/DEL

    넵 마치 부가 능력치가 굉장히 좋은 희귀 아이템이라도 얻은 기분입니다.

  3. 김동현 2008.12.04 17:32 PERM. MOD/DEL REPLY

    선명하게 다시 찍으면 다시 올려주세요. 저도 인쇄해서 한장 뽑아두고 싶네요. :)

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2008.12.05 12:40 신고 PERM MOD/DEL

    네 나중에 다시 찍어서 올려두겠습니다.

Write a comment.


스프링 프레임워크 3.0 m1 임박.

Spring/etc : 2008.11.29 13:36


참조: http://jira.springframework.org/browse/SPR?report=com.atlassian.jira.plugin.system.project%3Aroadmap-panel

아마도 S1A 컨퍼런스에 맞춰서 하나 공개하고 싶었는지 이슈를 뒤로(m2)좀 미룬거 같습니다. 캬오..

눈에 띄는 이슈 몇 가지는 흠..
- 내부 코드를 자바 5 기반으로 업그레이드
- @RequestMapping에서 URI 템플릿 기능 제공
- RSS/ATOM 뷰 지원
- @RequestParam에 defaultValue 속성 추가
- Expression Language Support(모르겠음)

흠.. REST는 m2에 추가되지만 이번에 추가되는 기능 중에 URI 템플릿 기능과 RSS 지원 기능 그리고 @RequeestParam에 defaultValue 속성 추가는 당장 개발에 써먹을 수 있어 보입니다. 하나 더 EL 기능에 대한 건 잘 파악이 안 됐는데 저게 JSF를 지원하는 기능인건지.. 아님 빈 XML 설정 파일에서 EL을 쓸 수 있게 해주겠다는 건지 좀 햇갈리네요. 자세히 봐야겠습니다.
top

Write a comment.


Toby's J2EE Development without EJB 정리

Spring/etc : 2008.11.21 15:04


이렇게 다른 사람의 자료를 정리해서 올리는 건 처음 인거 같네요. 제가 올렸던 글도 거의 정리를 안 하는데;; 전 사부님이 이런 글을 올렸었는지 몰랐습니다. 우왕;;

J2EE Development without EJB (1) - Why "J2EE Without EJB"?

J2EE Development without EJB (2) - Goal

J2EE Development without EJB (3) - Architecture

J2EE Development without EJB (4) - The Simplicity Dividened

J2EE Development without EJB (5) - EJB, Five Years On

J2EE Development without EJB (6) - Lightweight Container & IoC

J2EE Development without EJB 정리는 이만


안 그래도 어려운 책. 읽기 힘드시죠? 집어 던지고 싶으시죠? 시간만 잡아 먹는 것 같고, 머리만 아프고.. 일단 토비님이 정리한 걸 한 번 읽어 보신 다음에 다시 읽어보시면 조금 편하지 않을까요? 대충 문맥과 요점을 알고 보는거니깐 말이죠~

놀라운 사실은.. 글을 정리한 시점이 2004 ~ 2005년 자료라는 거... ㄷㄷㄷ 최근 글을 보니까 2004년 부터 사용하고 계셨던 것 같은데, 거의 4년을 앞서 달려온 셈입니다. 정말 놀라울 뿐입니다.
top

  1. Favicon of http://toby.epril.com BlogIcon 토비 2008.11.21 17:46 PERM. MOD/DEL REPLY

    2004년 말부터 쓴거야

    Favicon of http://whiteship.me BlogIcon 기선 2008.11.21 18:05 PERM MOD/DEL

    허걱 그러네요..

  2. arawn 2008.11.26 13:13 PERM. MOD/DEL REPLY

    앗... 숨어있는 이런 좋은 글이... ^^;;

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2008.11.26 15:05 신고 PERM MOD/DEL

    그러게요 ㅋㅋ

Write a comment.


스프링을 사용하는 애플리케이션의 성능 최적화 방안

Spring/etc : 2008.11.18 13:38


참조: Spring In Production White Paper
번역, 요약, 편역: 백기선

어떻게 하면 스프링을 사용한 애플리케이션의 성능을 향상 시킬 수 있을까?

처음으로 할 일은 성능을 측정하여 핫스팟을 발견하고 변경으로 인해 얻을 수 있는 이점을 정량화 한다. 최적화는 두 분류 효율적인 청사진 만들기(설정 튜닝하기)와 효율적인 런타임 기능 사용하기(애플리케이션 설계 최적화)로 나뉘어진다.

측정하기

튜닝은 측정부터.. 아파치 JMeter, Selenium 그리고 프로파일러를 사용한다. 스프링소스 컨설턴트들은 JAMon을 Spring AOP나 ApsectJ와 함께 사용해서 컴포넌트의 동작이나 요청 처리 경로를 프로파일링 할 때 좋은 성과를 봤다.

효율적인 청사진 만들기

효율적인 청사진 만들기의 비밀은 배포 플랫폼의 장점을 충분히 활용하는것에 있다. 스프링이 환경 종속적인 정보를 애플리케이션 코드 밖으로 빼내어 관리하기 때문에 이렇게 하는 것이 훨씬 쉽다.

데이터베이스 커넥션 풀의 경우, 애플리케이션 서버 위에서 실행하고 있다면 풀 설정을 관리자 콘솔에서 하고 스프링에는 JNDI를 통해 참조하도록 할 수 있다.

<jee:jndi-lookup id="dataSource"
    jndi-name="jdbc/MyDataSource"/>

이렇게 하면 두 가지 장점이 생긴다. 하나는 애플리케이션을 애플리케이션 서버 콘솔을 통해 운영팀이 관리하기 쉬워진다. 두 번째는 애플리케이션 서버 밴더가 커넥션 풀을 최적화 할 것이다.

같은 이유로 JMS ConnectionFactory 와 Destinationeh 애플리케이션 서버에 설정하고 JNDI로 얻어올 수 있다.

트랜잭션 관리의 경우도, 스프링은 커스텀 플랫폼 트랜잭션 매니저를 제공하여 여러분 배포 환경에 맞는 걸 사용할 수 있도록 해준다. ex) WebLogicJtaTransactionManager, Oc4jJtaTransactionManager,
스프링 2.5에 추가된 <tx:jta-transaction-manager/> 태그가 자동으로 기반으로 하고 있는 플랫폼을 찾아서 적절한 구현체를 선택할 것이다.

스프링 JMX를 사용하여 애플리케이션 자원을 노출할 때, 제품 플랫폼이 제공하는 MBeanServer와 연동하고 싶을 것이다. ex)  웹로직-JNDI (“java:comp/env/jmx/runtime”), WebSphereMBeanServerFactoryBean,
스프링 2.5에 추가된  <context:mbean-server ... /> 태그를 사용하면 자동으로 적절한 MBeanServer를 찾아준다.

이런 장점이 있지만, 통합 테스트를 애플리케이션 서버 밖에서 하고 싶을 것이다. 예를 들어, 기본적인 메시징 테스트는 ActiveMQ를 사요해서 하지만 실제 제품을 배포할 때는 IBM의 MQSeries를 사용할 수 있다. 스프링이 여러 설정 파일을 사용하는 기능이 있기 때문에 쉽게 처리할 수 있다. 우리는 모든 환경-독립적인 설정을 핵심 애플리케이션 설정에서 분리하는 것을 추천한다. 최선책은 애플리케이션 모듈 마다 하나의 설정 파일을 유지하는 것이다. 여기에 추가로 integration-test.xml 설정과 proeduction.xml 같은 설정을 정의할 수 있을 것이다. 통합 테스트를 할 때는 적절한 모듈 설정 파일과 integration-test.xml을 사용하여 application context를 만들면 된다. 배포할 때는 production.xml 파일을 사용하면 될 것이다.

이와 관련있는 설정으로 PropertyPlaceholderConfigurer는 설정 값을 외부화 하여 운영 팀에서 변경할 수 있도록 할 때 매우 유용하다. 스프링소스 컨설턴트가 성공적으로 사용하고 있는 방법은 다음과 같이 properties 파일을 연쇄적으로 사용하는 것이다.

1. classpath*:*.properties.local: 이에 해당하는 프로퍼티 파일들은 소스 코드 관리 시스템에 포함시키지 않느다. 개발자 마다 재정의해서 쓰도록 한다.

2. classpath*:META-INF/*.properties.default: 이 속성 파일들은 빌드에 의해 생성되는 애플리케이션 요소에 포함되며 기본 설정 값들을 가지고 있다. 프로젝트의 요구사항에 따라 이 수준은 생략할 수도 있다.

3. classpath*:*.properties: 이 파일들은 애플리케이션 요소들 밖에 존재두고, 운영팀에서 쉽게 수정할 수 있게 한다.

<context:property-placeholder
  location="classpath*:META-INF/*.properties.default,
classpath*:*.properties,
            classpath*:*.properties.local"/>

효율적인 청사진 만들기에 추가적으로 생각해 봐야 할 것들
  • 최적의 JDBC 커넥션 풀 갯수 찾아보기. 테스트 할 때 실제 배포 시나리오대로 해볼 것
  • 쓰레드 풀 구현체를 사용하는 스프링의 TaskExecutor를 사용할 때 최적의 쓰레드 풀 크기를 찾아볼 것. 처음은 CPU 갯수와 동일한 쓰레드 갯수로 설정해두고, 로컬 파일 I/O를 쓰면 쓰레드 하나를 추가하고. 네트워크 기반 I/O를 할 떈 또 몇 개를 추가하는 식으로..
  • read-only 트랜잭션일 경우에는 read-only 속성을 선언할 것. 이렇게 하면 하이버네이트를 사용하여 많은 객체를 데이터베이스에서 읽은 다음 아무 일도 하지 않았을 때 정말로 성능이 향상된다. 이렇게 하면 FlushMode.NEVER로 설정되기 때문에 세션에서 불필요한 dirth checking을 하지 않는다.
  • 만약 2단 커밋이 필요 없다면, JTA 대신에 로컬 트랜잭션 매니저 사용을 고려해 보라. 스프링은 HibernateTransactionManager를 통해서 정말 쉽게 JDBC와 Hibernate 데이터 접근을 동일한 트랜잭션에서 처리하게 해준다. 둘은 다른 방법으로 DB에 접근하지만 동일한 트랜잭션을 사용한다.
  • acknowledge=”transacted" 설정을 통해 메시지 리스너 컨테이너에 네이티브 JMS 트랜잭션 사용을 고려하라.

런타임 최적화하기

대부분의 엔터프라이즈 애플리케이션 성능 문제는 영속 계층으로부터 기인한다. Good performance here is often a function of sound design choices. 몇 가지 팁을 살펴보자.
  • ORM 툴을 사용할 때, eager와 lazy 로딩 전략의 균형을 잘 맞춰야 한다. 기본으로 로딩 지연을 사용하고, 특정 경우에만 fetch-join으로 튜닝하여 이른 로딩 장점을 활용한다. 쿼리를 튜닝할 때는 데이터 셋을 제품이 지금부터 향후 1년 간을 기준으로 하라.
  • ORM 툴이나 데이터베이스를 사용하여 로그에 SQL문이 보이도록 하라. 너무 많은 쿼리가 발생하는 이규가 생길 때 이를 쉽게 찾을 수 있다.
  • 하이버네이트를 사용할 때, 하이버네이트 Statistics 객체를 사용하여 런타임에 무슨 일이 벌어지는지 알 수 있게 하라. 프로그래밍을 통해 statics에 접근하거나, 스프링을 사용하여 하이버네이트 Statics MBean을 여러분의 MBean 서버에 노출시킬 수 있다. 프로그래밍을 통한 statics 객체 사용을 JUnit 테스트에 활용하여 여러분이 예측 가능한 쿼리가 얼마나 많이 발생하는지 확인하거나, 허용하는 쿼리 수를 기술 할 수 있다. 그 수를 벗어나면 테스트가 실패하도록.
  • 배치 스타일의 기능, 벌크 업데이트 또는 추가, 스토어드 프로시저는 보통 ORM 보다는 JDBC를 사용하는 것이 최선책이다. 스프링은 이들을 혼용하기 쉽게 해준다. 예를 들어 하이버네이트와 JDBC 데이터 접근을 동일한 트랜잭션으로 할 수 있다. 이 때 동일한 테이블을 사용하는 JDBC가 제대로 동작하려면 하이버네이트 세션을 적절한 시기에 flush 해주어야 한다.
  • 데이터베이스가 제공하는 기능을 활용하라.
    • 엑셀 스프레드시트를 일겅야 하는 애플리케이션에서 간단하게 변환하고 각 행을 SQL 서버 테이블에 넣어야 한다면 3시간이 걸리는 일도 SQL 서버 lined 쿼리를 사용하면 17초 만에 뚝딱.
    • 하이버네이트로 데이터 트리를 특정 뎁쓰로 변환하는 작업을 아무리 튜닝해도 시간도 오래 걸리고 메모리로 쫑나는데, 이걸 오라클의 스토어드 프로시저로 오라클의 계층 쿼리 기능으로 하니까 5초 미만으로 해결 됨.
    • flat 파일을 오라클 데이터베이스로 읽을 필요가 있을 때, 오라클 SQL 로더를 사용하여 데이터를 staging 테이블로 읽어들인다음, 스토어드 프로시저로 변경하고 데이터를 복사하여 원하는 테이블에 넣을 수 있다.
  • 만약 (비즈니스 로직은 전혀 없고)완전한 영속 로직만 있는 메소드가 있다면 데이터베이스의 스토어드 프로시저로 옮기고 스프링 JDBC를 사용하여 그것을 호출하라.
  • 읽기 전용 참조 데이터는 메모리 내부의 캐시에 둘 수 있다.
배치 애플리케이션은 추가적으로 고려할 것이 있다. 메소드 사용이 중요하기 때문이다. 스트림-기반 알고리즘이 최선의 선택이다. 예를 들어 컬렉션 보다는 이터레이터를 사용하라. 파일을 가지고 작업할 때, 만약 줄을 나눠야 한다면 스프링-기반이 아니라 캐릭터-기반을 사용하라. 우리는 이런 접근 방법을 사용하여 2백 50만 줄을 읽어 들인 적이 있다. 파싱하고 처리하는데 4초 미만이 걸렸고 메모리는 102K만 사용했다.

XML을 사용하는 배치 애플리케이션도 스트리밍을 사용하라. 우리는 280mb 파일에 들어있는 100,000개의 복잡한 XML 이벤트를 처리해야 할 필요가 있었다. DOM 기반의 접근 방법으로 2.5 시간이 걸렸고, 가비지 컬렉팅으로 9분이 필요했다. XML pull-parshing 기반 접근 방법으로 바꾸었더니 3초 만에 처리가 끝났고 200k 메모리를 사용했다.

또 다른 팁으로 단위 테스트와 통합 테스트를 할 때 java.lang.management 패키지에 있는 JVM 통계정보를 사용하는 것이다. 그것을 사용하면 CPU와 가비지 컬렉션 시간들을 확인할 수 있다.

데이터 계층을 위한 마지막으로 조언으로  every team benefits from access to a good DBA.

이밖에 스프링소스 컨설턴트로부터 얻은 다른 최적화 방안은 다음과 같다.
  • 스프링 배치 프로젝트가 제공하는 retry 기능을 사용하여 실패시 재시도가 필요할 때 사용할 수 있다.(예를 들어, 오라클 RAC의 개별 노드에서 실패한 기능의 경우) 사용자가 에러를 만나는 부담을 덜어줄 수 있다.
  • 웹 요소 랜더링 비용을 과소평가 하지 말아라. 트랜잭션 밖에서 되길 원할 것이다.(이부분 때문에 OSIV 패턴 이야기가 나왔군..)
  • application context를 요청 마다 새로 생성하지 말아라.
  • 스프링의 비동기 task executer를 사용하여 백그라운드에서 실행해도 될 작업을 사용자가 기다리게 하지 말아라.
  • 적절한 리모팅 프로토콜을 선택하라. 만약 SOAP 호환이 필요없다면, 스프링의 HttpInvoker 같이 간단한 스키마를 사용하는 것이 더 간단하고 빠를 것이다.
  • 스프링 AOP를 애플리케이션의 굉장히 여러 부분에 적용하고 있다면 ApsectJ 사용을 고려하라
스프링소스 컨설턴트들이 최적화에 도움을 얻은 참고자료는 다음과 같다.
  • Thomas Kyte's “Runstats.sql” test harness
  • “Effective Oracle by Design” (Thomas Kyte)
  • “Java Performance Tuning” (Jack Shirazi)
  • Sun's Java Performance Guides


top

Write a comment.