Spring概要とDI
 for Beginner

  2012/2/13
SpringFrameworkからSpringへ!?
SpringFramework概要
Spring
•  Spring Framework
  ‒  ロッド・ジョンソン氏(SpringSource[旧社名:
     Interface21])が中心に開発
  ‒  Java/JEEアプリケーション開発用フレームワーク
     •  DIxAOPコンテナ
  ‒  ASL(Apache Software Licence) Ver2.0に基づいたオープ
     ンソース




                                                   3
springsource.org
Springの年譜
•    2002年11月 書籍:Expert One-on-One J2EE
•    2004年3月 Spring 1.0
•    2004年9月 Spring 1.1
•    2005年5月 Spring 1.2
•    2006年10月 Spring 2.0
•    2007年11月 Spring2.5
•    2009年12月 Spring3.0
•    2011年12月 Spring3.1
     ‒  Java7, Spring Cache...
•  201x年 Spring3.2
     ‒  Hibernate4 FullSupport...



                                          5
Springの主なプロジェクト
•    Spring   AMQP          •  Spring Mobile
•    Spring   Android       •  Spring .NET
•    Spring   Batch         •  Spring Roo
•    Spring   BlazeDS       •  Spring Security
•    Spring   Data          •  Spring Security
•    Spring   Framework        OAuth
•    Spring   Gemfire        •  Spring Social
•    Spring   Integration   •  Spring Web Flow
                            •  Spring Web
                               Services

                                                 6
何があるのか、どこへ行くのか!?

SpringSource
springsource.com
SpringSourceの年譜
開発-実行-管理
Spring Roo
•  コマンドラインを利用してソースを自動生成するツール
 ‒  生産性の向上及び仕様変更や機能追加にも耐えうる継続的な開発
 ‒  Java界隈においてメジャーなフレームワークを利用
 ‒  自動生成した後もモデルクラスの変更に対して、ビューやコントロー
    ラクラスが自動で再作成される




                                      11
STS
•  SpringSource Tool Suite
   ‒  EclipseベースのSpringアプリケーション開発環境
   ‒  各種サーバへのデプロイ管理
VMforce
•  Force.comで実行可能なSpringアプリケーションを
   Javaで開発、実行、実行するためのサービス
•  Force.com
  ‒  リレーショナルデータベース、全文検索エンジン、レポートや
     分析、ユーザやアイデンティティ情報の管理...
vFabric
•  VMwareの今後の方向性を占うソリュー
   ション
 ‒  クラウド向けのアプリケーション基盤(ミド
    ルウェア)


          Spring Application	

               vFabric	

               VMware
vFabric
•  VMWare が提供する Java アプリケーションプラットホーム
   ‒  AP サーバーやデータベースやメッセージキューなどのソフトウェアを
      1セットで提供する
•  VMware vFabric Cloud Application Platform
   ‒  vSphere のメモリ管理機能を利用したコンピュータリソースの有効活
      用
   ‒  vCenter によるアプリケーションの監視
   ‒  仮想マシンの数に応じた価格体系を提供
tc Server
•  エンタープライズ向けにカスタマイズさ
   れた Tomcat
  ‒  開発者に馴染みの Tomcat互換
  ‒  Springを利用して作成したアプリケーション
     を実 行するのに適した環境
•  Tomcat + α
  ‒  Webベースの管理UI
  ‒  アプリケーションの設定とデプロイ管理
  ‒  パフォーマンスのモニターおよび状態の診断
ERS(Enterprise Ready Server)
•  Web サーバーとロードバランスの機能を提供
 ‒  Apache HTTP Server を使用
 ‒  Apache と比較して最大 100% のパフォーマンスアップ
•  迅速にバグフィックスするサポートを提供
 ‒  Apache HTTP Server のサポートを提供していた Covalent 社
    を SpringSource が買収




                                tc Server	

                    ERS	

                                tc Server
RabbitMQ
•  AMQP(Advanced Message Queuing Protocol) を実
   装したメッセージキュー
•  多彩なメッセージングのパターンに対応
  ‒  point-to-point, publishsubscribe,routing...
•  多彩なプロトコル、言語(クライアント側)に対応




                                                     Spring
                   RabbitMQ	
      tc Server	
                                                   Apprication	

                Cloud時代のスケール
                メッセージBus
GemFire
•  メモリーベースの分散型のデータ管理プラット
   ホーム(永続化も可能)
 ‒  Key-Value ストア ・マシンを動的に追加可能
 ‒  非同期のイベント通知




                                           Spring
            GemFire	
      tc Server	
                                         Apprication	

          Cloud時代のスケール	
          データストレージ
Hyperic
•  tc Serverの管理・監視・計測
  ‒  他のミドルウェアや OS リソースも監視できる
•  管理
  ‒  ランタイムインスタンスの起動・停止
  ‒  JVM オプション・ JDBC データソースなどの設定
  ‒  Web アプリケーションのデプロイ
•  監視
  ‒    リソースの閲覧・監視・コントロール
  ‒    デッドロックの検知
  ‒    ガベージコレクションの時間
  ‒    JDBC データソースの監視
•  計測
  ‒  instrumented 版の Spring Framework を利用し、 bean のメ
     ソッドの処理時間などを表示
これから!?
•  エンタープライズ開発
  ‒  Spring Framework + その他のプロダクト
•  プライベートCloud
  ‒  vFablic + vSphere
•  PaaS
  ‒  VMforce
  ‒  CloudFoundary
システム開発と部品化…
DIコンテナ
ソフトウェアを部品化したい
•  電気製品みたいなことがしたい!
 ‒  部品化 = インタフェース接続
部品化とインタフェース
•  インタフェースが穴の方
•  部品(コンポーネント)化するときに、インタ
   フェースをもつのは「偉い方」

     部品          部品


   ステレオ         スピーカ
インタフェースとレイヤ,パッケージ
•  変更単位や開発単位に適宜導入する
   ‒  レイヤ
       •  パソコン, ディスプレイ, キーボード...
   ‒  パッケージ(コンポーネント)
       •  パソコンの中のCPU, メモリ, HDD...

       表示の仕組み     業務の仕組み    永続化の仕組み
         プレゼン      ビジネス      データベース
        テーション      ロジック       アクセス

                                      RDB

ブラウザ



                                        25
インタフェースで分散開発
•  分割単位毎(レイヤ,パッケージ,コンポーネ
   ントなど)に、インタフェースを利用して、開
   発チームを分ける



   R           R        疑似
                    Q



       QImpl
   Q           疑似       QImpl
                    Q


                                26
インタフェース導入の難しさ
•  インタフェースの実装を、インタフェースを利用するク
   ラスが生成(インスタンス化)してはいけない


public class R {               ②利用
・・・                                     QImpl
Q q = new QImpl(); // ダメ   R          (Qの実装)
q.methodA();                     Q
String m
  = q.methodB();
・・・                             ①生成




                                                27
インタフェース導入とFactory
•  インタフェースの実装を生成(インスタンス化)する
   Factory(FactoryMethod)を用意(自作)すること
   で解決する

public class R {	
                     ③利用	
・・・	
                                                QImpl
Q q =	
                                   R               (Qの実装)
  (Q)Factory.create(KEY);	
               Q
                              ①生成の	
q.methodA();	
                 要求	
String m 	
                                            ②生成	
                                         Factory
  = q.methodB();	
・・・	

                                                    KEY=QImpl



                                                             28
Factoryの例
          ③利用	
                         QImpl
     R                 (Qの実装)
              Q
①生成の	
 要求
                               ②生成	
             Factory


                                KEY=QImpl


public static Object create(String keyName) {
  // keyNameを元にファイルを読み込んで、生成するクラス名を取得する	
  Class<?> clazz = Class.forName(createName);
  Object obj = clazz.newInstance();
  return obj;
}

                          29
Factoryにもうひと工夫
•  Webアプリケーションは、マルチスレッドで動作する
•  マルチスレッド配下の(ステートレスな)処理は、スレッド単にイ
   ンスタンス化するのではなく、システム内に1つあれば良い

                      :Employee
         インスタンス化	
    ServiceImpl

        :FindAction   :Employee
                      ServiceImpl
        マルチスレッド	
                      :Employee
                      ServiceImpl


                                            インスタンス化	

                                                  :Employee
                                    :FindAction
                                                  ServiceImpl
                                    マルチスレッド	

                                                                30
FactoryをSingleton対応にする
•  1度インスタンス化されたクラスは、2回目のインスタ
   ンス化のリクエストに対して、同じインスタンスを返し
   てしまえば良い
     ‒  クラスのSingleton化が不要                        はしょってる
                                                 ので注意	
private EmployeeServiceImpl empService = null;
・・・	
public static Object create(String keyName) {
 // keyNameが同じだったら、リターン	
 return (Object)EmpService;
 // 初めてのkeyNameだったら、シンクロナイズして以下を実行	
 Class<?> clazz = Class.forName(createName);

    Object obj = clazz.newInstance();
    return obj;
}

                                                      31
DIコンテナを利用する!
•  Factoryではなく、DIコンテナを使用することでインタ
   フェースが容易に扱える
•  しかも、Factoryのようにソースコードに現れない

public class R {	
  @Autowired	
                                              QImpl
  private Q q;	
         R                  (Qの実装)
  ・・・	
                            Q
  q.methodA();	
  String m 	
     = q.methodB();	
  ・・・	
                          DIコンテナ	
                        ②セット	
                ①生成	

   DIコンテナ導入後	

                                                      32
ようやくDIの登場!
•  DI(Dependency Injection)
  ‒  依存性の注入
•  インタフェースの導入が楽

                     ③利用	
    EmpServiceImpl                    DB2EmpDao
                       EmpDao
             ②セット	
             (依存性の注入)	
                                  ①生成	

                      DIコンテナ	



                             33
Singletonへの対応
•  一般的に利用されているDIxAOPコンテナ
   であれば、インスタンスをSingletonとし
   て生成するか、リクエスト毎にインスタ
   ンス化のどちらかを選ぶことができる
 ‒  Spring,Seasar2 ...etc




                     34
SpringでおこなうDI
•  アノテーションの利用
 ‒  Spring2.x系以降、アノテーションの利用が増えてい
    る(大規模開発や大手SI便だでは定義ファイルの利用
    が多い)
 ‒  メリット:定義ファイルの管理が不要
 ‒  デメリット:プログラマにアノテーションを意識
•  定義ファイルの利用
 ‒  Springの基本
 ‒  メリット:プログラマにSpringを意識させない
 ‒  デメリット:定義ファイルの管理



                               35
アノテーションを使った

INJECTION!
アノテーションを利用したDI
•  インジェクションの設定(自動検出)
  ‒  @Autowired
•  Beanの設定
  ‒  @Component
                      Injection

 class Service {                  @Component
   @Autowired                     class DaoImpl
   private Dao dao;                implements Dao {
  ...                              ...
 }                        Dao     }



                                                      37
主なインジェクションの設定
•  @Autowired
  ‒  byType
  ‒  プロパティ,コンストラクタ,メソッドで有
     効
  ‒  複数のパラメータやコレクション型に対応
  ‒  @Autowired(required=false)
•  @Qualifier
  ‒  @Autowiredと組み合わせてbyName
  ‒  @Qualifier("hogeImpl");


                38
主なBeanの設定
•  @Component
 ‒  SpringのBeanとして扱う
 ‒  @Component( 任意の名前 )も可能。省略時
    はクラス名の先頭小文字

      ...
      @Component
      public class Hoge {
      ...




                            39
問題 こんなことできる?
public class Hoge {
  @Autowired                 public class Hoge {
  private Fuga f;              @Autowired
  @Autowired                   public Hoge(Fuga f, FugaFuga ff) {...}
  private FugaFuga ff;         @Autowired
                               public m(Fuga f, FugaFuga ff) {...}



     @Component
     public class FugaImpl      @Component
       implements Fuga {        public class FugaFugaImpl
       ...                        implements FugaFuga {
     }                            ...
                                }


                                 40
アノテーションでも必要。Bean定義ファイル

<?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-3.0.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context-3.0.xsd">

  <context:annotation-config />
  <context:component-scan base-package="sample.di.*"/>

</beans>



                                    41
タグ解説
•  <context:annotation-config />
  –  @Autowired,@Resourceを利用する場合
•  <context:component-scan
  base-package= "パッケージ名, ・・・"/>
  –  @Component,@Serviceなどを利用する場合"
  ‒  base-packageで指定したパッケージ名以下のコン
     ポーネントを検索する




                      42
その他のスキーマ一覧
   名称	
          スキーマ                              URI	
                         説明	
                 ファイル	
utilスキーマ	
   spring-util.xsd   http://www.springframework.org/schema/util   定数定義やプロパティ
                                                                            ファイルの読み込み等
                                                                            のユーティリティ機能
                                                                            の設定を簡略化	
jeeスキーマ	
    spring-jee.xsd    http://www.springframework.org/schema/jee    JNDIのlookupおよび、
                                                                            EJBのlookupの設定を
                                                                            簡略化	
langスキーマ	
   spring-lang.xsd   http://www.springframework.org/schema/lang   スクリプト言語による設
                                                                            定を簡略化	


aopスキーマ	
    spring-aop.xsd    http://www.springframework.org/schema/aop    AOPの設定を簡略化	



txスキーマ	
     spring-tx.xsd     http://www.springframework.org/schema/tx     トランザクションの設定
                                                                            を簡略化	




                                                                                        43
問題 2つあったら?
•  Autowireでインタフェースを実装するク
   ラスが2つあったらどうなる?

class Service {            @Component
  @Autowired               class ADaoImpl
  private Dao dao;          implements Dao {
 ...                        ...
}                    Dao   }


                           @Component
                           class BDaoImpl
                            implements Dao {
                            ...
                           }
問題 じゃあ、Unitテストどうする?


class Service {            @Component
  @Autowired               class DaoImpl
  private Dao dao;          implements Dao {
 ...                        ...
}                    Dao   }


                           @Component
                           class TestDaoImpl
                            implements Dao {
                            ...
                           }
解答の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"
   xmlns:context="http://www.springframework.org/schema/context”
   xsi:schemaLocation=“
  http://www.springframework.org/schema/beans
                                       ワイルドカードはやめて、
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                                      コンポーネント毎に宣言する	
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context-3.0.xsd">

  <context:annotation-config />
  <context:component-scan base-package="sample.di.service"/>
  <!-- <context:component-scan base-package="sample.di.dataaccess"/> -->
  <context:component-scan base-package="test"/>
</beans>


                                     46
問題 インターフェイスがない?


class Service {      @Component
  @Autowired         class Dao {
  private Dao dao;    ...
 ...                 }
}
問題 1つもなかったら?
•  Autowireでインタフェースを実装するク
   ラスがなかったらどうなるか?

     class Service {
       @Autowired
       private Dao dao;
      ...
     }                    Dao
レイヤ毎のBeanの設定
•  全て@Componentの拡張
•  @Controller
  ‒  プレゼン層SpringMVC用
•  @Service
  ‒  ビジネス層Service用
  ‒  トランザクション管理ができるとか                    はありました…
•  @Repository
  ‒  データアクセス層DAO用
  ‒  例外を全てDataAccessExceptionに変換

              ...
              @Service
              public class Hoge {
              ...

                                    49
主なBeanスコープ
•  @Scope
  ‒  @Componentと併用。Beanのスコープを決める
  ‒  省略時はsingleton
  ‒  @Scope( Value属性 )
  ‒  Value属性
    •  singleton・・・シングルトン
    •  prototype・・・その都度インスタンス生成

        ...
        @Component
        @Scope(“prototype”)
        public class Hoge {
        ...


                                   50
Web用のBeanスコープ
•  @Scope
  ‒  Value属性
    •  request・・・Servlet APIのrequestスコープ
    •  session・・・Servlet APIのsessionスコープ


        ...
        @Component
        @Scope(“session”)
        public class Hoge {
        ...




                                           51
ライフサイクル
•  @PostConstruct
•  @PreDestroy

 public class Hoge {
     ...
     @PostConstruct
     public void start() {...}
     @PreDestroy                 ...
     public void stop() {...}    <context:annotation-config />
 ...                             ...




                                                                 52
ここには地獄があった?
定義ファイルでINJECTION
Bean定義ファイルの基本
•  アノテーションを利用することにより、
   Bean定義ファイルの記述負荷は減った
•  しかし、最低限の知識は必要
 ‒  スキーマの設定
 ‒  Beanの設定
•  大規模開発で、アノテーションをプログ
   ラマに書かせるのはやっぱり嫌だ!
 ‒  というのもある



              54
Bean定義ファイル
<?xml version="1.0" encoding="UTF-8"?>        contextがないことに注意
<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-3.0.xsd">

 <bean id = "service"
        class = "sample.di.service. ServiceImpl">
     <property name = "dao" ref = "dao"/>
 </bean>
 <bean id = "dao"
        class = "sample.di.dataaccess.DaoImpl" />
</beans>



                                    55
主要タグの主な属性
<bean>
      属性	
                    意味	
id           システム内で一意とするオブジェクト名。	
name         Bean定義ファイル内で、id以外に名前を設定したい場合に設
               定する別名。	
             空白、「,」、「;」で区切ることにより、複数の値を設定できる。	
class        idの実態。パッケージ名+クラス名。	

<property>
      属性	
                    意味	
name         ref属性で指定したオブジェクトをインジェクションする属性の名
                前。「set + “name属性で指定した属性名”」のメソッドを利用
                する(属性名は使われないことに注意)。	
ref          インジェクションしたいbeanのid(beanタグのid属性で指定され
               た名前)。	

                                                 56
セッタインジェクション
 ServiceImpl                             DaoImpl
                              Dao
      setDao

                         Spring




     public class ServiceImpl implements Service {
       private Dao dao;

         public void setDao(Dao dao) {
           this. dao = dao;
         }
     …




                             57
定義ファイル
 ServiceImpl                            DaoImpl
                                Dao
      setDao
                        Spring


   ・・・
   <bean id = service"
      class = com.starlight.business.ServiceImpl">
      <property name = dao ref = dao"/>
      </property>
   </bean>

   <bean id = dao"
     class = com.starlight.dataaccess.DaoImpl" />
   ・・・



                           58
定義ファイル
      ServiceImpl                               DaoImpl
                                        Dao
              setDao
                                Spring




・・・
<bean id =    service"
  class =    com.starlight.business.ServiceImpl" autowire="byType" />
<bean id =    dao"
  class =    com.starlight.dataaccess.DaoImpl" />
・・・




                                   59
問題 じゃあ、これはどうなる?
•  クラス図を書いてみてください

・・・
<bean id="hogeService"
       class="sample.HogeServiceImpl">
   <property name = "hogeDao" ref = "hogeDao"/>
   <property name = "hogehogeDao" ref = "hogehogeDao"/>
</bean>

<bean id = "hogeDao" class = "sample.HogeDaoImpl" />
<bean id = "hogehogeDao" class = "sample.HogehogeDaoImpl" />
・・・
問題 エラー?どうして?
•  前の問題の続きです。エラーの原因はなんでしょう

public class HogeServiceImpl {
   private HogeDaoImpl hd;
   private HogehogeDaoImpl hhd;

...
      public void setHd (HogeDaoImpl hd) {
        this.hd = hd;
      }

      public void setHhd(HogehogeDaoImpl hhd) {
        this.hhd = hhd;
      }
}
おまけ
サンプルを起動したいとき
    •  Springをお試しで使う例です
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

     public static void main(String[] args) {
          // 定義ファイルを読んで、コンテナを生成
          ApplicationContext ctx
             = new ClassPathXmlApplicationContext("/sample/config/applicationContext.xml");

          // コンテナからコンポーネントの取り出し
          ProductService productService = (ProductService) ctx.getBean("productService");

          // コンポーネントの動作確認
          Product product = productService.getProduct();
          System.out.println(product);
     }
}
Spring3.1概要x di

Spring3.1概要x di