2009年10月29日木曜日

Spring 2.5/JSR-250

Spring 2.5 の JSR-250 対応APIを調べてみる。 具体的には、@Resource, @PostConstruct, @PreDestroy という三つのアノテーションで、以下のような、無味乾燥なコードで挙動を確かめてみたい。(ただしローカル前提とし、@Resource の JNDI LookUp は度外視する。)
package net.xad.spring25.trial1.jsr250_2;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;

@Service
public class ServiceA {
   @Resource
   private ServiceB serviceB;

   private boolean initialized = false;
   private boolean cleanedUp = false;

   @PostConstruct
   private void initialize() {
      initialized = true;
   }
   @PreDestroy
   private void cleanUp() {
      cleanedUp = true;
   }
   public boolean isInjectedCorrectly() {
      return null != serviceB;
   }
   public boolean isInitializedCalled() {
      return initialized;
   }
   public boolean isCleanUpCalled() {
      return cleanedUp;
   }
}
ソースの意味は以下
  • フィールド serviceB はリソースとしてインジェクトされる beanで、クラスServiceBは以下のような定義。単なる実験用なので、以下のような空実装で手を抜く。
    package net.xad.spring25.trial1.jsr250_2;
    import org.springframework.stereotype.Service;
    @Service public class ServiceB {}
  • フィールド initialized は、@PostConstruct が付いたメソッド initialize()が呼ばれた時、false から true になる。
  • フィールド cleanedUp は、@PreDestroy が付いたメソッド cleanUp() が呼ばれた時、false から true になる。
  • ※ serviceB に setter が無い事と、serviceB, initialize(), cleanUp()が private である事に注意。
この ServiceAクラスを以下のようなテストクラスで確かめてみる。
package net.xad.spring25.trial1.jsr250_2;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.junit.Test;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppTest {
   @Test
   public void testApp() {
      AbstractApplicationContext ctx = new ClassPathXmlApplicationContext(
         "classpath:application-context.xml");

      ServiceA serviceA = (ServiceA)ctx.getBean("serviceA");

      //ServiceB がちゃんとインジェクト済み
      assertTrue(serviceA.isInjectedCorrectly());
      //initialize() が呼ばれた
      assertTrue(serviceA.isInitializedCalled());
      //cleanUp() はまだ呼ばれてない
      assertFalse(serviceA.isCleanUpCalled());

      ctx.close();
      //cleanUp() が呼ばれた
      assertTrue(serviceA.isCleanUpCalled());
   }
}
プロジェクトは以下のように作る。
  • maven-archetype-quickstart でプロジェクト作成
  • 自動生成の不要ファイルを削除する
  • 上記ソースを、適当に作成
  • pom.xml の dependencies を以下のように編集
       <dependencies>
          <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring</artifactId>
             <version>2.5.6</version>
          </dependency>
          <dependency>
             <groupId>mysql</groupId>
             <artifactId>mysql-connector-java</artifactId>
             <version>5.1.10</version>
          </dependency>
          <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <version>4.7</version>
          </dependency>
       </dependencies>
    
  • 以下のような application-context.xml を、src/main/resources などに追加。
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:context="http://www.springframework.org/schema/context"
     xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
    
     <context:component-scan base-package="net.xad.spring25.trial1" />
    </beans>
ビルド・エラー等が無い事を確認して、AppTest.java上 の Alt+Shift+Tで実行。 上手くいったことを確認。めでたしめでたし。

0 件のコメント:

コメントを投稿