SlideShare uma empresa Scribd logo
1 de 67
Baixar para ler offline
AOPとMVC
for Beginner

 2012/2/20
問題
•  インスタンス変数に宣言したのと同じ型
   のインスタンスをインジェクションして
   もらうためのアノテーションは?
•  インスタンス化され、インジェクション
   されるために、クラス宣言の前に書くア
   ノテーションは?
•  結局、DIコンテナって何のためにあるの
   か?


                         2
前回の続き
•  SpringのDIを使って、部品化はできた
   (気がする)
•  でも・・・
 ‒  ログなどの共通処理部分が部品に残っている
 ‒  例外処理も部品化を壊している
•  それに・・・
 ‒  トランザクション管理は面倒だし、難しい




                           3
Springの説明の前に・・・

AOPの基本


                  4
AOPを使ってもっと部品化する
•  AOPを使えば処理を後からクラスに追加できる
 ‒  例:トレースログを追加する

                           find()を呼ぶ	
                DaoImpl	
      ServiceImpl	
                                                 find()	
                                         Dao

                                          public class DaoImpl extends Dao{	
 >java ・・・	
                                  ・・・	
 16:00:01 *Start*   find() DaoImpl	
          public List find() {	
 16:00:02 *End*     find() DaoImpl	
              List list = select();	
 17:02:12 *Start*   find() DaoImpl	
              return list;	
 17:02:13 *End*     find() DaoImpl	
          }	
                                          }	
           実行結果	

                                                                                5
AOPをもう少し正しく
Adviceを追加できるときが
     Joinpointとなる	
      Joinpointを条件で絞り込む
                                 フィルター	

                                 Aspect

                      Pointcut              Advice

       ソースコード	

                      Pointcut              Advice

          Joinpoint


                                          追加したい処理	


                                                      6
Joinpoint
•  Adviceを追加できるとき(ポイント)
•  AOPの仕様であり、実装者は変更できない
•  Joinpointの仕様例
 ‒  メソッドの開始時、終了時
 ‒  プロパティが利用されたとき

            DaoImpl
       add()
       delete()
       find()
       update()
                      Joinpoint
                      例:メソッドの開始時や終了時	

                                     7
Pointcut
•  Joinpointに達した命令を、Adviceまで到
   達させるか否かフィルタリングするフィ
   ルター

                                 Joinpointを条件「add*」で絞り込む	


                         DaoImpl               Pointcut

                      add()
                      delete()                            Advice
ServiceImpl	
         find()
                Dao   update()
                                   Joinpoint
                                               追加したい処理	

                                                                   8
Befor Advice
•  Joinpointの前で実行される


                             メソッドの実行前に割り込む	



           method()
                      Before Advice
  Client                                          Servant
                                       return
                                      Exception




                                                            9
After Advice
•  Joinpointの後で実行される



            method()

   Client                                     Servant
                   After Advice    return
                                  Exception

                メソッドの実行後に割り込む	




                                                        10
After Returning Advice
•  Joinpointが正常終了した後に実行される


              method()
                                          return
   Client        After Returning Advice            Servant

                                    Exception
            メソッドの実行後に正常終了時
            に割り込む	




                                                             11
Around Advice
•  Joinpointの前後で実行される


           method()                   method()
  Client              Around Advice    return     Servant

                                      Exception


                 メソッドの実行前と実行後、例
                 外発生時にも割り込む	




                                                            12
Throw Advice
•  Joinpointで例外が発生した時に実行される



           method()
  Client                                   Servant
                                return
                Throw Advice   Exception


              例外発生時に割り
              込む	




                                                     13
問題
•  メソッドの開始と終了のログをとりた
   かったら?
•  メソッドが正常終了したログをとりた
   かったら?
•  メソッドが異常終了したときのログをと
   りたかったら?




                        14
AOPの仕組み例
•  Proxyベースの場合、ProxyオブジェクトはSpringが自動生成する




                                 :Bean
                                             :Advice

                         処理の
           処理の依頼	
                         依頼	
                                           Adviceの呼び出し	



 :Client                         :Proxy            :Spring
                 Interface
                                          自動生成	


                                               Bean定義
                 Pointcutの参照	
                  ファイル	

                                                             1-15
AOPの主な利用方法
•  各クラスに記述されている同一の処理を抜き出し、ひと
   まとめにして、既存のクラスに後から追加する
 ‒  ライブラリとの違い
   •  ライブラリは呼び出さないといけない
   •  AOPは勝手に追加される
•  追加すると便利な処理
 ‒  トランザクション管理
   •  トランザクション管理は難しいくプログラマに任せられない
 ‒  ログ管理
   •  メソッドの開始と終了のトレースログが正しく出力されない
     ‒  誰もフォーマットを守らない
     ‒  トレースログを追加し忘れる
 ‒  例外管理
   •  処理の途中でExceptionが握りつぶされてしまう
     ‒  Exceptionを実行時例外にする

                                    16
AOPでやらない方が良いこと
•  個別の処理(特定業務の処理、デバッ
   グ)
 ‒  プログラマが個別にAOPをいれるのは不可
  •  そこで何をやっているのかが分からなくなる


•  業務アプリのプログラマではなく、基盤
   チームとかが使う技術!?




                            17
SpringのAOP
•  定義ファイルの利用
 ‒  Spring1.x系では基本
•  アノテーションの利用
 ‒  Spring2.x系以降、アノテーションの利用が増
    えている(大規模開発や大手SI便だでは定義
    ファイルの利用が多い)




                            18
問題 書いてないけど?
•  例えば
 ‒  アノテーション
   •  メリット:定義ファイルの管理が不要
   •  デメリット:プログラマにアノテーションを意識
 ‒  とか、定義ファイルのメリットとかデメリット




                               19
アノテーションを使った
AOP


              20
アスペクトの例
•  アノテーションの利用
@Aspect
public class AspectMessage {

    @After("execution(* exMethod())")
    public void hoge() {
      // メソッド終了後に動くAdvice
      System.out.println("after called");
    }
}
                                            21
アノテーション一覧
•  アノテーションを利用したAOP
    ‒  Bean定義ファイルの記述が簡潔になる
    ‒  ソースコードに記述することで管理が煩雑

 アノテーション         	
                      説明 	
@Aspect               Adviceとなるクラスを指定するアノテーション     	
@Around               Around Adviceとなるメソッドを指定するアノテーション 	
@Before               Before Adviceとなるメソッドを指定するアノテーション	
@After                After Adviceとなるメソッドを指定するアノテーション	
@AfterReturning                                               	
                      After Returning Adviceとなるメソッドを指定するアノテーション
@AfterThrowing        After Throwing Adviceとなるメソッドを指定するアノテーション	

                                                              22
アドバイス詳細(1)
•  Before, After
   ‒  @After( Primitiveポイントカット )
      •  メソッド名は任意、メソッドのパラメータと戻り値はなしでも可能。
         メソッド内で、アスペクト対象となっているメソッド名やパラメー
         タ,戻り値などの取得をする場合は、パラメータにJoinPoint
      •  メソッド内で、アスペクト対象となっているメソッドを呼び出す必
         要はない


    @Before(“execution(* exMethod())”)
    public void hoge() {
        ・・・
    }	

                                         23
アドバイス詳細(2)
•  Around
  ‒  @Around( Primitiveポイントカット )
    •  メソッド名は任意、メソッドのパラメータには必
       ずProceedingJoinPointが必要、戻り値はアスペ
       クト対象のメソッドにあわせる
    •  メソッド内で、アスペクト対象となっているメ
       ソッドを呼び出す必要がある
      ‒  ProceedingJoinPoint#proceed()メソッド
          »  Object proceed() throws Trowable
    •  メソッド内で、アスペクト対象となっているメ
       ソッド名やメソッドのパラメータの取得は
       ProceedingJoinPointを介しておこなう

                                                24
アドバイス詳細(3)
•  Around
  ‒  戻り値はアスペクト対象にあわせる
public String getMessage() {
    return “hello!”;                アスペクト対象のメソッド
 }	

 @Around(“execution(* getMessage())”)
 public String fuga(ProceedingJoinPoint pjp)
                            throws Throwable {;
    String msg = (String)pjp.proceed();
    return msg;
 }	

                                                   25
アドバイス詳細(4)
public int getFigure() {
    return 100;            アスペクト対象のメソッド
 }	

 @Around(“execution(* getFigure())”)
 public int fuga(ProceedingJoinPoint pjp)
                              throws Throwable {;
    Integer figure= (Integer)pjp.proceed();
    return figure.intValue();
 }	

                                                    26
アドバイス詳細(5)
•  Around
  ‒  ProceedingJoinPointの使い方

  メソッド名の取得

  Signature sig = pjp.getSignature();
  System.out.println("Sig: " + sig.getName());	

          パラメータの取得(最初のパラメータ)

          Object[] os = pjp.getArgs();
          System.out.println("Args: " + os[0]);	

                                                    27
問題∼重複してたらどうなる?
@Around(“execution(* add())”)
public int hoge (ProceedingJoinPoint pjp)
                            throws Throwable {;
  Integer figure= (Integer)pjp.proceed();
  return figure.intValue();              これと同じhogehogeメソッド
}                                            が存在したら?


private int x;
public int add(int i) {
   x = x + i;                     アスペクト対象のメソッド
   return x;
 }	
                                                       28
アドバイス詳細(6)
•  AfterReturning
  ‒  @AfterReturning(value= Primitiveポイント
     カット , returnig = 戻り値の変数名 )
    •  メソッド名は任意、メソッドのパラメータはアス
       ペクト対象となっているメソッドの戻り型とアノ
       テーションのretuning属性で指定した変数名
    •  メソッド内で、アスペクト対象となっているメ
       ソッドを呼び出す必要はない




                                        29
アドバイス詳細(7)
public String exMethod() {
    return “hello!”;             アスペクト対象のメソッド

 }	



 @AfterReturning(value=“execution(* exMethod())”,
                                           returning=“ret”)
 public String hoge(String ret) {
     System.out.println(“Return: “ + ret);
 }	


                                                              30
アドバイス詳細(8)
•  AfterThrowing
  ‒  @AfterReturning(value= Primitiveポイント
     カット , throwing = 例外の変数名 )
    •  メソッド名は任意、メソッドのパラメータはアス
       ペクト対象となっているメソッドの戻り型とアノ
       テーションのthrowing属性で指定した変数名
    •  メソッド内で、アスペクト対象となっているメ
       ソッドを呼び出す必要がない




                                        31
アドバイス詳細(9)

 @AfterThrowing(value=“execution(* exMethod())”,
                              throwing=“ex”)
 public String foo(HogeException ex) {
     System.out.println(“Exception Msg: “ + ex.getMessage());
 }	




                                                            32
アドバイス詳細(10)
•  AfterThrowing
 @AfterThrowing(value=“execution(* exMethod())”, throwing=“ex”)
 public String foo(Throwable ex) {
   System.out.println(“Exception Msg: “ + ex.getMessage());
 }
 @AfterThrowing(value=“execution(* exMethod()”, throwing=“ex”)
 public String var(HogeException ex) {
   System.out.println(“Exception Msg: “ + ex.getMessage());
 }
 @AfterThrowing(value=“execution(* exMethod()”, throwing=“ex”)
 public String hoge(Exception ex) {
   System.out.println(“Exception Msg: “ + ex.getMessage());
 }


                                                                  33
問題∼どのアドバイス?
•  前ページの実装があったとき、どこかの
   プログラムがExceptionを投げてよこしま
   した
•  どのアドバイスが動くでしょう?




                         34
Primitiveポイントカット
  Primitive	
 ポイントカット        	
                      概要 	
execution	
          呼出先の「メソッド」、「コンストラクタ」を指定する。      	
within	
             呼出元の「クラス」を指定する。

                     withinをPointcutに指定すると、指定されたクラスから呼出される、メソッ
                     ド等が選択されることになる。

                     対象は、指定されたクラスで宣言されたメソッドに限定され、指定された
                     クラスの親クラスで宣言されたメソッド内は対象外となる。          	
this	
               呼出元の「クラス」を指定する。

                     thisをPointcutに指定すると、指定されたクラスから呼出される、メソッド
                     等が選択されることになる。

                     withinとは、親クラスで定義されたメソッドの呼出しも対象とする点が異な
                     る。	
target	
             呼出先の「クラス」を指定する。

                     ただし、呼出先のstaticフィールドは対象外となる。     	
args	
               呼出先「メソッド」の引数の型を指定する。       	
※Primitiveポイントカット:あらかじめ用意されているポイントカットのこと	


                                                               35
executionの基本構文
•  execution(メソッドの修飾子△メソッドの戻り値型△
   パッケージ.クラスまたはインタフェース.メソッド名
   (仮引数の型|,仮引数の型…|) △throws 例外)

•  「メソッドの修飾子(publicやprivateは省略可能)」や
   「throws△例外」は省略することが可能
•  メソッドの戻り値型、パッケージやクラス名、インタ
   フェース名にはワイルドカード(*)の利用が可能
•  仮引数に(..)を記述すると任意の個数の引数と一致さ
   せることが可能




                                  36
ポイントカットで利用できる論理演算子
論理                                               説明	
演算子	
|| または    論理和を意味する論理演算子	
or	
          例)
          execution(* *..AopExBean.exMethod()) or execution(* *..AopExBeanParent.exMethod())
           →AopExBeanのメソッドexMethodまたはAopExBeanParentのメソッドexMethodを指定	
&& また     論理積を意味する論理演算子	
は and	
          例)
          execution(* *..AopExBean.exMethod()) && execution(* *..AopExBeanParent.exMethod())
             →AopExBeanのメソッドexMethodまたはAopExBeanParentのメソッドexMethodを指定
! または     否定を意味する論理演算子。	
not	
          例)
          execution(* exMethod()) and not execution(* *..AopExBeanParent.*())
           →AopExBeanParent以外のクラス(インタフェース)のメソッドexMethodを指定	


                                                                                        37
コーディング例(1)
@Aspect
public class AspectMessage {

  @After("execution(* exMethod())")
  public void after() {
    // メソッド終了後に動作するAdvice
    System.out.println("after called");
  }

  @Before("execution(* exMethod())")
  public void before() {
    // メソッド開始時に動作するAdvice
    System.out.println("before called");
  }



                                           38
コーディング例(2)

@Around("execution(* exMethod())")
 public void around(ProceedingJoinPoint pjp) throws Throwable {
   // メソッド呼出の前後に動作するAdvice
   System.out.println("pre proceed");
   pjp.proceed();
   System.out.println("post proceed");
 }




                                                                  39
コーディング例(3)
    @AfterReturning(value="execution(* exMethod())", returning="ret")
    public void afterReturning(String ret) {
      // メソッド呼出が例外の送出なしに終了した際に動作するAdvice
      System.out.println("after returning called");
      System.out.println("return value = " + ret);
    }

    @AfterThrowing(value="execution(* exMethod())", throwing="ex")
    public void afterThrowing(Throwable ex) {
      // メソッド呼出が例外の送出なしに終了した際に動作するAdvice
      System.out.println("after throwing called");
      System.out.println("exception value = " + ex.toString());
    }
}



                                                                        40
定義ファイル
<?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
  xmlns:aop=http://www.springframework.org/schema/aop
  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
   http://www.springframework.org/schema/aop
   http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
…
  <aop:aspectj-autoproxy/>
…
</beans>



                                                                          41
定義ファイルには書かないでしょ!?
AOP


                    42
それでも書きたい定義ファイル(1)

  	
 ・・・
<aop:config>
     <aop:aspect id="myAspect" ref="aspectMessage">
         <aop:pointcut id="fuga"
                expression="execution(* getMessage())"/>
         <aop:before pointcut-ref="fuga" method="foo"/>
         <aop:after pointcut-ref="fuga" method="var"/>
         <aop:around pointcut-ref="fuga" method="hoge"/>
     </aop:aspect>
</aop:config>




                                                           43
それでも書きたい定義ファイル(2)
<aop:config>
   <aop:aspect id="myAspect2" ref="aspectMessage2">
       <aop:pointcut id="fuga2"
              expression="execution(* getMessage())"/>
       <aop:after pointcut-ref="fuga2" method="hoge"/>
   </aop:aspect>
</aop:config>
・・・
<bean id="aspectMessage" class="sample.aop.AspectMsg" />
<bean id="aspectMessage2" class="sample.aop.AspectMsg2" />
・・・




                                                         44
コーディング例
public class AspectMessage {

  public void after() {
    // メソッド終了後に動作するAdvice
    System.out.println("after called");
  }

  public void before() {
    // メソッド開始時に動作するAdvice
    System.out.println("before called");
  }

・・・以下省略




                                           45
問題 消すことできる?

<aop:config>
   <aop:aspect id="myAspect2" ref="aspectMessage2">
       <aop:pointcut id="fuga2"
              expression="execution(* getMessage())"/>
                   beanを定義している2行	
       <aop:after pointcut-ref="fuga2" method="hoge"/>
   </aop:aspect>
</aop:config>
・・・
<bean id="aspectMessage2" class="sample.aop.AspectMsg2" />
<bean id="aspectMessage2" class="sample.aop.AspectMsg" />
・・・



                                                             46
今までの知識を使ってWebアプリケーションを改善する


DIとAOPのまとめ
アーキテクチャ・リファクタリング

                             47
アーキテクチャ・リファクタリング(1/5)

                                  Employee
                       Employee
          FindAction               MySql     RDB
                        Service
                                    Dao
 ブラウザ	



•  表示と永続化のフレームワーク導入済
•  インタフェース未使用(もちろんDI,AOPも)
 ‒  チーム開発がしずらい
 ‒  変更、機能拡張、テストが容易ではない
•  連続性も阻害
 ‒  Conecctionの引き回し、検査時例外の伝搬


                                                   48
アーキテクチャ・リファクタリング(2/5)
インタフェースの導入	
                        Employee                    Employee
                        Service                     Dao
                                   <<Singleton>>               <<Singleton>>
           FindAction               Employee                    Employee       MySQL
                                   ServiceImpl                  DaoMySql
ブラウザ	
                                                                          RDB
            利用	
              利用	
                                             生成	
                      生成	
                                         Factory

   •  メリット
         ‒  インタフェースを区切りとして、チーム開発がやりやすくなった
         ‒  変更、機能拡張、テストが容易になった
   •  デメリット
         ‒  Factoryを実装する必要がある
         ‒  クラスはFactoryに依存する

                                                                                  49
アーキテクチャ・リファクタリング(3/5)

DIの導入	
                         Employee                 Employee
                         Service                  Dao
                                     Employee                Employee
         FindAction                                                     MySQL
                                    ServiceImpl              DaoMySql

ブラウザ	
                                                                   RDB
                                            生成	
                 生成	

             Injection                               Injection
                                    DIコンテナ	


  •  Factoryを実装する必要がない
  •  クラスはDIコンテナに依存しない

                                                                           50
アーキテクチャ・リファクタリング(4/5)
  DIコンテナ導入後のソースコード	

                •    トランザクション管理やログ出力、例外処理が残っている
  Employee            ‒  分岐が多いため、テストの量が多くなる
 ServiceImpl          ‒  共通化できる部分が隠蔽できていない
                      ‒  例外処理とConnectionの引き渡しによる連続性の阻害がある

public class EmployeeServiceImpl"                       } catch(Exception e) {!
 implements EmployeeService{"                             conn.rollback();!
 @Autowired!                                              ・・・	
 private EmployeeDao dao;"                               } finally {!
 ・・・	
                                                    conn.close();!
 public List findAll() throws Exception {!                 ・・・	
  if(Log.flag) { System.out.println(“***Start”); }!       }!
  Connection conn = null;"                              if(Log.flag) { System.out.println(“***End”); }"
  ・・・	
                                                 return employeeList;"
   //EmployeeDao dao !                                }"
  //     = (EmployeeDao)Factory.create(KEY);!
                                                     ・・・	
  List employeeList = null;"
  try {"
     employeeList = dao.findAll(conn);"
     conn.commit();!


                                                                                                 51
アーキテクチャ・リファクタリング(5/5)
     AOP導入後のソースコード	
•    共通ライブラリを廃止してAOPを導入
•    連続性の確保
     ‒  トランザクション管理、ログ出力、例外処理はAOPで実現しているため、ソースコード上から
        はなくなっている
     ‒  Advice実装されており、なくなっている訳ではない
•    ソースコードの記述量が減り、バグの数も低下、開発者の作業も軽減
•    テストの容易性も向上

     public class EmployeeServiceImpl !    書くことがなくなりました・・・!
            implements EmploeeService {!
        @Autowired!
        private EmployeeDao dao;!

          public List findAll() {!
            return dao.findAll();!
         }!
     ・・・	




                                                              52
アーキテクチャ・リファクタリングの嘘
•  AOPで業務例外(例えば、在庫がなかった時に
   どうする)は処理できないから、そんなに奇麗
   に例外は消えない(多分…)
•  だって、AOPを使う基盤チームは業務を知らな
   い(多分…)。だから、業務例外はAOPで提供
   できない
•  それに業務例外がAOPになったら、業務プログ
   ラムが読めない!
•  そもそも、業務例外にExceptionを使うのって
   どうよ(!?)という問題でもある


                           53
かる∼く
Spring MVC


             54
Spring MVCとは
•  Spring Frameworkに含まれるWeb
   MVCフレームワーク
 ‒  初期のSpring Frameworkの段階から含まれ
    ている
 ‒  StrutsやJSFと競合
•  特徴
 ‒  DIコンテナとの親和性
 ‒  きれいな設計
   •  インタフェースを使用して部品化


                              55
Spring MVCのController

DIの導入	
                         Employee                 Employee
                         Service                  Dao
                                     Employee                Employee
         XxxController                                                  MySQL
                                    ServiceImpl              DaoMySql

ブラウザ	
                                                                   RDB
                  生成	
                      生成	
                 生成	

                                                     Injection
              Injection
                                    DIコンテナ	




                                                                           56
難しいと評判(?)のSpring MVC
•  Spring1.xのSpring MVC
  ‒  設定が難しい
  ‒  作り方がよくわからない
  ‒  日本語の情報が少ない
  ‒  そもそも知らない




                          57
簡単になったSpring MVC
•  Spring 3.xのSpring MVC
  ‒  Springの新機能を導入
    •  アノテーションにより設定がシンプルになり、わ
       かりやすくなった
    •  component-scanにより設定ファイルが最低限で
       すむようになった
  ‒  あいかわらず日本語の情報は少ない
    •  英語のマニュアルを読みましょう




                                  58
デモ
•  STS(SpringSource Tool Suite)で作成
 1.  メニューからNew->Project
 2.  SpringSource Tool Suite->Spring
     Template Projectを選択
 3.  Spring MVC Projectを選択




                                       59
動作概要

                            <<controller>>
                                                              Model	
                            HomeController	
            "serverTime"	


                                                                Date
                            home()	
            ③	
           (現在の日時)	

               Dispatcher
ブラウザ	
   ①	
     Servlet
               (ほか色々)	



                                   <<jsp>>
                            /WEB-INF/views/home.jsp	
                ⑥	




                                                                         60
HomeController
                 DIコンテナにより
                 自動で読み込まれる
                 (component-scan)	
                                        HTTPメソッドがGETで
@Controller                             「/」へアクセスした際に
public class HomeController {           実行される	

    @RequestMapping(value = "/", method = GET)
    public String home(Model model) { Viewに渡したいオブジェクトを
      Date date = new Date();         設定する	

        model.addAttribute("serverTime", date);

        return "home";
    }
                            View名をreturnする	
}

                                         ※少し手を加えシンプルにしています	
                                                          61
home.jsp

<html>
<head>
 <title>Home</title>                    Modelに設定したオブジェクトは
</head>                                 自動的にHttpServletRequestに
                                        設定されている	
<body>
<h1>Hello world! </h1>
<p>The time on the server is ${serverTime}.</p>
</body>
</html>

                                   ※少し手を加えシンプルにしています	




                                                              62
@RequestMapping色々

// 一つのメソッドに複数のURLを割り当て
@RequestMapping({"/", "/home"})
public String home() { ・・・

// 一つのURLでHTTPメソッドごとにメソッドを切り分け
@RequestMapping(value="/foo", method=GET)
public String doGetMethod() { ・・・

@RequestMapping(value="/foo", method=POST)
public String doPostMethod() { ・・・



                                             63
引数色々①
// リクエストパラメータを取得(「/person?id=10」などでアクセス)
@RequestMapping(value = "/person", method=GET)
public String showPerson1 (
     @RequestParam("id") int id, Model model) {
   Person person = findById(id);
   model.addAttribute("person", person);
   ・・・

// URLの値を取得(「/person/10」などでアクセス)
@RequestMapping(value = "/person/{id}", method=GET)
public String showPerson2(
     @PathVariable("id") int id, Model model) {
   Person person = findById(id);
   model.addAttribute("person", person);
   ・・・

                                                      64
引数色々②
// 画面からの入力をマッピング(formからデータを送信)
@RequestMapping(value = "/person", method = POST)
public String registerPerson(@ModelAttribute Person person) {
   register(person);
   ・・・



// ほかにも色々
@RequestMapping("/foo")
public String foo(
     Model model, WebRequest req, WebResponse res,
     Cookie cookie, Locale locale,
     HttpServletRequest sreq, HttpServletResponse sres) {
   ・・・

                                                                65
その他の機能
•  Session管理
   ‒  @SessionAttributes(model名)をクラスに設定すると、Modelに追加
      したオブジェクトはHttpSessionに追加される
   ‒  @ModelAttribute(model名)を引数に設定すると、Sessionのオブジェ
      クトが引数に渡される
   ‒  SessionStatus#setComplete()でHttpSession内のオブジェクトが破
      棄される
      •  ControllerごとにSession内のオブジェクトを管理可能
•  入力チェック(Validation)
   ‒  JSR-303(Bean Validation)に対応
      •  @NotNull String id;
      •  @Length(max = 30) String name;
   ‒  Validation対象の引数に@Validを設定する
•  例外処理
   ‒  例外発生時に実行するメソッドに@ExceptionHandler
      (FooException.class)

                                                      66
BON VOYAGE!




              67

Mais conteúdo relacionado

Mais procurados

インターネットの仕組みとISPの構造
インターネットの仕組みとISPの構造インターネットの仕組みとISPの構造
インターネットの仕組みとISPの構造Taiji Tsuchiya
 
ドメイン駆動設計 本格入門
ドメイン駆動設計 本格入門ドメイン駆動設計 本格入門
ドメイン駆動設計 本格入門増田 亨
 
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)NTT DATA Technology & Innovation
 
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャー
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャーKubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャー
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャーToru Makabe
 
Amazon Elastic MapReduce with Hive/Presto ハンズオン(講義)
Amazon Elastic MapReduce with Hive/Presto ハンズオン(講義)Amazon Elastic MapReduce with Hive/Presto ハンズオン(講義)
Amazon Elastic MapReduce with Hive/Presto ハンズオン(講義)Amazon Web Services Japan
 
GraalVMの多言語実行機能が凄そうだったので試しにApache Sparkに組み込んで動かしてみたけどちょっとまだ早かったかもしれない(Open So...
GraalVMの多言語実行機能が凄そうだったので試しにApache Sparkに組み込んで動かしてみたけどちょっとまだ早かったかもしれない(Open So...GraalVMの多言語実行機能が凄そうだったので試しにApache Sparkに組み込んで動かしてみたけどちょっとまだ早かったかもしれない(Open So...
GraalVMの多言語実行機能が凄そうだったので試しにApache Sparkに組み込んで動かしてみたけどちょっとまだ早かったかもしれない(Open So...NTT DATA Technology & Innovation
 
SQL大量発行処理をいかにして高速化するか
SQL大量発行処理をいかにして高速化するかSQL大量発行処理をいかにして高速化するか
SQL大量発行処理をいかにして高速化するかShogo Wakayama
 
20210127 今日から始めるイベントドリブンアーキテクチャ AWS Expert Online #13
20210127 今日から始めるイベントドリブンアーキテクチャ AWS Expert Online #1320210127 今日から始めるイベントドリブンアーキテクチャ AWS Expert Online #13
20210127 今日から始めるイベントドリブンアーキテクチャ AWS Expert Online #13Amazon Web Services Japan
 
PostgreSQLレプリケーション10周年!徹底紹介!(PostgreSQL Conference Japan 2019講演資料)
PostgreSQLレプリケーション10周年!徹底紹介!(PostgreSQL Conference Japan 2019講演資料)PostgreSQLレプリケーション10周年!徹底紹介!(PostgreSQL Conference Japan 2019講演資料)
PostgreSQLレプリケーション10周年!徹底紹介!(PostgreSQL Conference Japan 2019講演資料)NTT DATA Technology & Innovation
 
コンテナ未経験新人が学ぶコンテナ技術入門
コンテナ未経験新人が学ぶコンテナ技術入門コンテナ未経験新人が学ぶコンテナ技術入門
コンテナ未経験新人が学ぶコンテナ技術入門Kohei Tokunaga
 
Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)
Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)
Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)NTT DATA Technology & Innovation
 
Fluentdのお勧めシステム構成パターン
Fluentdのお勧めシステム構成パターンFluentdのお勧めシステム構成パターン
Fluentdのお勧めシステム構成パターンKentaro Yoshida
 
DynamoDB設計のちょっとした技
DynamoDB設計のちょっとした技DynamoDB設計のちょっとした技
DynamoDB設計のちょっとした技Yoichi Toyota
 
DockerとPodmanの比較
DockerとPodmanの比較DockerとPodmanの比較
DockerとPodmanの比較Akihiro Suda
 
ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方増田 亨
 
メルカリ・ソウゾウでは どうGoを活用しているのか?
メルカリ・ソウゾウでは どうGoを活用しているのか?メルカリ・ソウゾウでは どうGoを活用しているのか?
メルカリ・ソウゾウでは どうGoを活用しているのか?Takuya Ueda
 
Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方Taku Miyakawa
 
REST API、gRPC、GraphQL 触ってみた【2023年12月開催勉強会資料】
REST API、gRPC、GraphQL 触ってみた【2023年12月開催勉強会資料】REST API、gRPC、GraphQL 触ってみた【2023年12月開催勉強会資料】
REST API、gRPC、GraphQL 触ってみた【2023年12月開催勉強会資料】洵貴 佐川
 

Mais procurados (20)

インターネットの仕組みとISPの構造
インターネットの仕組みとISPの構造インターネットの仕組みとISPの構造
インターネットの仕組みとISPの構造
 
ドメイン駆動設計 本格入門
ドメイン駆動設計 本格入門ドメイン駆動設計 本格入門
ドメイン駆動設計 本格入門
 
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
 
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャー
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャーKubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャー
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャー
 
Amazon Elastic MapReduce with Hive/Presto ハンズオン(講義)
Amazon Elastic MapReduce with Hive/Presto ハンズオン(講義)Amazon Elastic MapReduce with Hive/Presto ハンズオン(講義)
Amazon Elastic MapReduce with Hive/Presto ハンズオン(講義)
 
GraalVMの多言語実行機能が凄そうだったので試しにApache Sparkに組み込んで動かしてみたけどちょっとまだ早かったかもしれない(Open So...
GraalVMの多言語実行機能が凄そうだったので試しにApache Sparkに組み込んで動かしてみたけどちょっとまだ早かったかもしれない(Open So...GraalVMの多言語実行機能が凄そうだったので試しにApache Sparkに組み込んで動かしてみたけどちょっとまだ早かったかもしれない(Open So...
GraalVMの多言語実行機能が凄そうだったので試しにApache Sparkに組み込んで動かしてみたけどちょっとまだ早かったかもしれない(Open So...
 
SQL大量発行処理をいかにして高速化するか
SQL大量発行処理をいかにして高速化するかSQL大量発行処理をいかにして高速化するか
SQL大量発行処理をいかにして高速化するか
 
20210127 今日から始めるイベントドリブンアーキテクチャ AWS Expert Online #13
20210127 今日から始めるイベントドリブンアーキテクチャ AWS Expert Online #1320210127 今日から始めるイベントドリブンアーキテクチャ AWS Expert Online #13
20210127 今日から始めるイベントドリブンアーキテクチャ AWS Expert Online #13
 
PostgreSQLレプリケーション10周年!徹底紹介!(PostgreSQL Conference Japan 2019講演資料)
PostgreSQLレプリケーション10周年!徹底紹介!(PostgreSQL Conference Japan 2019講演資料)PostgreSQLレプリケーション10周年!徹底紹介!(PostgreSQL Conference Japan 2019講演資料)
PostgreSQLレプリケーション10周年!徹底紹介!(PostgreSQL Conference Japan 2019講演資料)
 
コンテナ未経験新人が学ぶコンテナ技術入門
コンテナ未経験新人が学ぶコンテナ技術入門コンテナ未経験新人が学ぶコンテナ技術入門
コンテナ未経験新人が学ぶコンテナ技術入門
 
Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)
Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)
Dapr × Kubernetes ではじめるポータブルなマイクロサービス(CloudNative Days Tokyo 2020講演資料)
 
Fluentdのお勧めシステム構成パターン
Fluentdのお勧めシステム構成パターンFluentdのお勧めシステム構成パターン
Fluentdのお勧めシステム構成パターン
 
DynamoDB設計のちょっとした技
DynamoDB設計のちょっとした技DynamoDB設計のちょっとした技
DynamoDB設計のちょっとした技
 
DockerとPodmanの比較
DockerとPodmanの比較DockerとPodmanの比較
DockerとPodmanの比較
 
ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方
 
メルカリ・ソウゾウでは どうGoを活用しているのか?
メルカリ・ソウゾウでは どうGoを活用しているのか?メルカリ・ソウゾウでは どうGoを活用しているのか?
メルカリ・ソウゾウでは どうGoを活用しているのか?
 
Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方
 
REST API、gRPC、GraphQL 触ってみた【2023年12月開催勉強会資料】
REST API、gRPC、GraphQL 触ってみた【2023年12月開催勉強会資料】REST API、gRPC、GraphQL 触ってみた【2023年12月開催勉強会資料】
REST API、gRPC、GraphQL 触ってみた【2023年12月開催勉強会資料】
 
DevOps with Database on AWS
DevOps with Database on AWSDevOps with Database on AWS
DevOps with Database on AWS
 
Goss入門
Goss入門Goss入門
Goss入門
 

Destaque

Spring3.1概要 データアクセスとトランザクション処理
Spring3.1概要 データアクセスとトランザクション処理Spring3.1概要 データアクセスとトランザクション処理
Spring3.1概要 データアクセスとトランザクション処理土岐 孝平
 
Twitter sphere of #twitter4j #twtr_hack
Twitter sphere of #twitter4j #twtr_hackTwitter sphere of #twitter4j #twtr_hack
Twitter sphere of #twitter4j #twtr_hackkimukou_26 Kimukou
 
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsug
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsugSpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsug
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsugY Watanabe
 
Javaでやってみる The Twelve Factor App JJUG-CCC 2014 Fall 講演資料
Javaでやってみる The Twelve Factor App JJUG-CCC 2014 Fall 講演資料Javaでやってみる The Twelve Factor App JJUG-CCC 2014 Fall 講演資料
Javaでやってみる The Twelve Factor App JJUG-CCC 2014 Fall 講演資料Y Watanabe
 
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Springドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring増田 亨
 

Destaque (9)

Spring3.1概要x di
Spring3.1概要x diSpring3.1概要x di
Spring3.1概要x di
 
Spring3.1概要 データアクセスとトランザクション処理
Spring3.1概要 データアクセスとトランザクション処理Spring3.1概要 データアクセスとトランザクション処理
Spring3.1概要 データアクセスとトランザクション処理
 
SpringMVC
SpringMVCSpringMVC
SpringMVC
 
Twitter sphere of #twitter4j #twtr_hack
Twitter sphere of #twitter4j #twtr_hackTwitter sphere of #twitter4j #twtr_hack
Twitter sphere of #twitter4j #twtr_hack
 
Springの今
Springの今Springの今
Springの今
 
Spring AMQP × RabbitMQ
Spring AMQP × RabbitMQSpring AMQP × RabbitMQ
Spring AMQP × RabbitMQ
 
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsug
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsugSpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsug
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsug
 
Javaでやってみる The Twelve Factor App JJUG-CCC 2014 Fall 講演資料
Javaでやってみる The Twelve Factor App JJUG-CCC 2014 Fall 講演資料Javaでやってみる The Twelve Factor App JJUG-CCC 2014 Fall 講演資料
Javaでやってみる The Twelve Factor App JJUG-CCC 2014 Fall 講演資料
 
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Springドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
 

Semelhante a Spring3.1概要 AOP & MVC

試験にでるSpring
試験にでるSpring試験にでるSpring
試験にでるSpring土岐 孝平
 
Ec cube開発合宿 プラグインセミナー
Ec cube開発合宿 プラグインセミナーEc cube開発合宿 プラグインセミナー
Ec cube開発合宿 プラグインセミナーAyumu Kawaguchi
 
継続的デリバリー読書会 第 5 章 デプロイメントパイプラインの解剖学
継続的デリバリー読書会 第 5 章 デプロイメントパイプラインの解剖学継続的デリバリー読書会 第 5 章 デプロイメントパイプラインの解剖学
継続的デリバリー読書会 第 5 章 デプロイメントパイプラインの解剖学Takuma SHIRAISHI
 
企業におけるSpring@日本springユーザー会20090624
企業におけるSpring@日本springユーザー会20090624企業におけるSpring@日本springユーザー会20090624
企業におけるSpring@日本springユーザー会20090624Yusuke Suzuki
 
作る人から作りながら運用する人になっていく
作る人から作りながら運用する人になっていく作る人から作りながら運用する人になっていく
作る人から作りながら運用する人になっていくRyo Mitoma
 
Spring Day 2016 springの現在過去未来
Spring Day 2016 springの現在過去未来Spring Day 2016 springの現在過去未来
Spring Day 2016 springの現在過去未来Yuichi Hasegawa
 
カスタムSIで使ってみよう ~ OpenAI Gym を使った強化学習
カスタムSIで使ってみよう ~ OpenAI Gym を使った強化学習カスタムSIで使ってみよう ~ OpenAI Gym を使った強化学習
カスタムSIで使ってみよう ~ OpenAI Gym を使った強化学習Hori Tasuku
 
規模の見積もり WACATE 2016 winter
規模の見積もり WACATE 2016 winter 規模の見積もり WACATE 2016 winter
規模の見積もり WACATE 2016 winter Tomoaki Fukura
 
[Okta x Jamf合同新年会] Okta Workflowsによるノーコード業務改善 〜Jamf APIを使ってMac端末情報を自動収集してみよう〜
[Okta x Jamf合同新年会] Okta Workflowsによるノーコード業務改善 〜Jamf APIを使ってMac端末情報を自動収集してみよう〜[Okta x Jamf合同新年会] Okta Workflowsによるノーコード業務改善 〜Jamf APIを使ってMac端末情報を自動収集してみよう〜
[Okta x Jamf合同新年会] Okta Workflowsによるノーコード業務改善 〜Jamf APIを使ってMac端末情報を自動収集してみよう〜Ryo Sasaki
 
LT13(前半)Workshipにおけるレコメンドエンジン実装
LT13(前半)Workshipにおけるレコメンドエンジン実装LT13(前半)Workshipにおけるレコメンドエンジン実装
LT13(前半)Workshipにおけるレコメンドエンジン実装GIG inc.
 
Chainerで学ぶdeep learning
Chainerで学ぶdeep learningChainerで学ぶdeep learning
Chainerで学ぶdeep learningRetrieva inc.
 
CPU / GPU高速化セミナー!性能モデルの理論と実践:理論編
CPU / GPU高速化セミナー!性能モデルの理論と実践:理論編CPU / GPU高速化セミナー!性能モデルの理論と実践:理論編
CPU / GPU高速化セミナー!性能モデルの理論と実践:理論編Fixstars Corporation
 
アジャイル開発&TFS導入
アジャイル開発&TFS導入アジャイル開発&TFS導入
アジャイル開発&TFS導入You&I
 
TotalViewを使った代表的なバグに対するアプローチ
TotalViewを使った代表的なバグに対するアプローチTotalViewを使った代表的なバグに対するアプローチ
TotalViewを使った代表的なバグに対するアプローチRWSJapan
 
iOSやAndroidアプリ開発のGoodPractice
iOSやAndroidアプリ開発のGoodPracticeiOSやAndroidアプリ開発のGoodPractice
iOSやAndroidアプリ開発のGoodPracticeKen Morishita
 
はじめてのCodeIgniter
はじめてのCodeIgniterはじめてのCodeIgniter
はじめてのCodeIgniterYuya Matsushima
 
Azure Api Management 俺的マニュアル 2020年3月版
Azure Api Management 俺的マニュアル 2020年3月版Azure Api Management 俺的マニュアル 2020年3月版
Azure Api Management 俺的マニュアル 2020年3月版貴志 上坂
 
Angular2 rc.1 unit testing overview
Angular2 rc.1 unit testing overviewAngular2 rc.1 unit testing overview
Angular2 rc.1 unit testing overviewMitsuru Ogawa
 

Semelhante a Spring3.1概要 AOP & MVC (20)

試験にでるSpring
試験にでるSpring試験にでるSpring
試験にでるSpring
 
Ec cube開発合宿 プラグインセミナー
Ec cube開発合宿 プラグインセミナーEc cube開発合宿 プラグインセミナー
Ec cube開発合宿 プラグインセミナー
 
継続的デリバリー読書会 第 5 章 デプロイメントパイプラインの解剖学
継続的デリバリー読書会 第 5 章 デプロイメントパイプラインの解剖学継続的デリバリー読書会 第 5 章 デプロイメントパイプラインの解剖学
継続的デリバリー読書会 第 5 章 デプロイメントパイプラインの解剖学
 
企業におけるSpring@日本springユーザー会20090624
企業におけるSpring@日本springユーザー会20090624企業におけるSpring@日本springユーザー会20090624
企業におけるSpring@日本springユーザー会20090624
 
作る人から作りながら運用する人になっていく
作る人から作りながら運用する人になっていく作る人から作りながら運用する人になっていく
作る人から作りながら運用する人になっていく
 
Spring Day 2016 springの現在過去未来
Spring Day 2016 springの現在過去未来Spring Day 2016 springの現在過去未来
Spring Day 2016 springの現在過去未来
 
Wacate2015summer_report
Wacate2015summer_reportWacate2015summer_report
Wacate2015summer_report
 
カスタムSIで使ってみよう ~ OpenAI Gym を使った強化学習
カスタムSIで使ってみよう ~ OpenAI Gym を使った強化学習カスタムSIで使ってみよう ~ OpenAI Gym を使った強化学習
カスタムSIで使ってみよう ~ OpenAI Gym を使った強化学習
 
規模の見積もり WACATE 2016 winter
規模の見積もり WACATE 2016 winter 規模の見積もり WACATE 2016 winter
規模の見積もり WACATE 2016 winter
 
[Okta x Jamf合同新年会] Okta Workflowsによるノーコード業務改善 〜Jamf APIを使ってMac端末情報を自動収集してみよう〜
[Okta x Jamf合同新年会] Okta Workflowsによるノーコード業務改善 〜Jamf APIを使ってMac端末情報を自動収集してみよう〜[Okta x Jamf合同新年会] Okta Workflowsによるノーコード業務改善 〜Jamf APIを使ってMac端末情報を自動収集してみよう〜
[Okta x Jamf合同新年会] Okta Workflowsによるノーコード業務改善 〜Jamf APIを使ってMac端末情報を自動収集してみよう〜
 
LT13(前半)Workshipにおけるレコメンドエンジン実装
LT13(前半)Workshipにおけるレコメンドエンジン実装LT13(前半)Workshipにおけるレコメンドエンジン実装
LT13(前半)Workshipにおけるレコメンドエンジン実装
 
Chainerで学ぶdeep learning
Chainerで学ぶdeep learningChainerで学ぶdeep learning
Chainerで学ぶdeep learning
 
CPU / GPU高速化セミナー!性能モデルの理論と実践:理論編
CPU / GPU高速化セミナー!性能モデルの理論と実践:理論編CPU / GPU高速化セミナー!性能モデルの理論と実践:理論編
CPU / GPU高速化セミナー!性能モデルの理論と実践:理論編
 
アジャイル開発&TFS導入
アジャイル開発&TFS導入アジャイル開発&TFS導入
アジャイル開発&TFS導入
 
TotalViewを使った代表的なバグに対するアプローチ
TotalViewを使った代表的なバグに対するアプローチTotalViewを使った代表的なバグに対するアプローチ
TotalViewを使った代表的なバグに対するアプローチ
 
継続的8章
継続的8章継続的8章
継続的8章
 
iOSやAndroidアプリ開発のGoodPractice
iOSやAndroidアプリ開発のGoodPracticeiOSやAndroidアプリ開発のGoodPractice
iOSやAndroidアプリ開発のGoodPractice
 
はじめてのCodeIgniter
はじめてのCodeIgniterはじめてのCodeIgniter
はじめてのCodeIgniter
 
Azure Api Management 俺的マニュアル 2020年3月版
Azure Api Management 俺的マニュアル 2020年3月版Azure Api Management 俺的マニュアル 2020年3月版
Azure Api Management 俺的マニュアル 2020年3月版
 
Angular2 rc.1 unit testing overview
Angular2 rc.1 unit testing overviewAngular2 rc.1 unit testing overview
Angular2 rc.1 unit testing overview
 

Mais de Yuichi Hasegawa

Spring 5でSpring Testのここが変わる_公開版
Spring 5でSpring Testのここが変わる_公開版Spring 5でSpring Testのここが変わる_公開版
Spring 5でSpring Testのここが変わる_公開版Yuichi Hasegawa
 
thymeleafさいしょの一歩
thymeleafさいしょの一歩thymeleafさいしょの一歩
thymeleafさいしょの一歩Yuichi Hasegawa
 
マイクロサービス入門(Spring fest 2017)
マイクロサービス入門(Spring fest 2017)マイクロサービス入門(Spring fest 2017)
マイクロサービス入門(Spring fest 2017)Yuichi Hasegawa
 
20170525 jsug バッチは地味だが役に立つ
20170525 jsug バッチは地味だが役に立つ20170525 jsug バッチは地味だが役に立つ
20170525 jsug バッチは地味だが役に立つYuichi Hasegawa
 
Application Re-Architecture Technology ~ StrutsからSpring MVCへ ~
Application Re-Architecture Technology ~ StrutsからSpring MVCへ ~Application Re-Architecture Technology ~ StrutsからSpring MVCへ ~
Application Re-Architecture Technology ~ StrutsからSpring MVCへ ~Yuichi Hasegawa
 
こどもの絵本 ヒトラーとナチ
 こどもの絵本 ヒトラーとナチ こどもの絵本 ヒトラーとナチ
こどもの絵本 ヒトラーとナチYuichi Hasegawa
 
Spring知っておきたい
Spring知っておきたいSpring知っておきたい
Spring知っておきたいYuichi Hasegawa
 
Spring4-DevLove発表資料
Spring4-DevLove発表資料Spring4-DevLove発表資料
Spring4-DevLove発表資料Yuichi Hasegawa
 
[Jjug]java small object programming
[Jjug]java small object programming[Jjug]java small object programming
[Jjug]java small object programmingYuichi Hasegawa
 
[豆ナイト]Java small object programming
[豆ナイト]Java small object programming[豆ナイト]Java small object programming
[豆ナイト]Java small object programmingYuichi Hasegawa
 
Jjug springセッション
Jjug springセッションJjug springセッション
Jjug springセッションYuichi Hasegawa
 

Mais de Yuichi Hasegawa (15)

Spring 18年の歴史
Spring 18年の歴史Spring 18年の歴史
Spring 18年の歴史
 
Spring 5でSpring Testのここが変わる_公開版
Spring 5でSpring Testのここが変わる_公開版Spring 5でSpring Testのここが変わる_公開版
Spring 5でSpring Testのここが変わる_公開版
 
Enterprise Microservice
Enterprise MicroserviceEnterprise Microservice
Enterprise Microservice
 
thymeleafさいしょの一歩
thymeleafさいしょの一歩thymeleafさいしょの一歩
thymeleafさいしょの一歩
 
マイクロサービス入門(Spring fest 2017)
マイクロサービス入門(Spring fest 2017)マイクロサービス入門(Spring fest 2017)
マイクロサービス入門(Spring fest 2017)
 
20170525 jsug バッチは地味だが役に立つ
20170525 jsug バッチは地味だが役に立つ20170525 jsug バッチは地味だが役に立つ
20170525 jsug バッチは地味だが役に立つ
 
Application Re-Architecture Technology ~ StrutsからSpring MVCへ ~
Application Re-Architecture Technology ~ StrutsからSpring MVCへ ~Application Re-Architecture Technology ~ StrutsからSpring MVCへ ~
Application Re-Architecture Technology ~ StrutsからSpring MVCへ ~
 
こどもの絵本 ヒトラーとナチ
 こどもの絵本 ヒトラーとナチ こどもの絵本 ヒトラーとナチ
こどもの絵本 ヒトラーとナチ
 
Jsug 20160422 slides
Jsug 20160422 slidesJsug 20160422 slides
Jsug 20160422 slides
 
Spring知っておきたい
Spring知っておきたいSpring知っておきたい
Spring知っておきたい
 
Spring4-DevLove発表資料
Spring4-DevLove発表資料Spring4-DevLove発表資料
Spring4-DevLove発表資料
 
[Jjug]java small object programming
[Jjug]java small object programming[Jjug]java small object programming
[Jjug]java small object programming
 
[豆ナイト]Java small object programming
[豆ナイト]Java small object programming[豆ナイト]Java small object programming
[豆ナイト]Java small object programming
 
Jjug springセッション
Jjug springセッションJjug springセッション
Jjug springセッション
 
Spring3.1 aop-mvc
Spring3.1 aop-mvcSpring3.1 aop-mvc
Spring3.1 aop-mvc
 

Último

自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineerYuki Kikuchi
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?akihisamiyanaga1
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfFumieNakayama
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...博三 太田
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NTT DATA Technology & Innovation
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)UEHARA, Tetsutaro
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)Hiroshi Tomioka
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfFumieNakayama
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案sugiuralab
 

Último (9)

自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
 

Spring3.1概要 AOP & MVC

  • 2. 問題 •  インスタンス変数に宣言したのと同じ型 のインスタンスをインジェクションして もらうためのアノテーションは? •  インスタンス化され、インジェクション されるために、クラス宣言の前に書くア ノテーションは? •  結局、DIコンテナって何のためにあるの か? 2
  • 3. 前回の続き •  SpringのDIを使って、部品化はできた (気がする) •  でも・・・ ‒  ログなどの共通処理部分が部品に残っている ‒  例外処理も部品化を壊している •  それに・・・ ‒  トランザクション管理は面倒だし、難しい 3
  • 5. AOPを使ってもっと部品化する •  AOPを使えば処理を後からクラスに追加できる ‒  例:トレースログを追加する find()を呼ぶ DaoImpl ServiceImpl find() Dao public class DaoImpl extends Dao{ >java ・・・ ・・・ 16:00:01 *Start* find() DaoImpl public List find() { 16:00:02 *End* find() DaoImpl List list = select(); 17:02:12 *Start* find() DaoImpl return list; 17:02:13 *End* find() DaoImpl } } 実行結果 5
  • 6. AOPをもう少し正しく Adviceを追加できるときが Joinpointとなる Joinpointを条件で絞り込む フィルター Aspect Pointcut Advice ソースコード Pointcut Advice Joinpoint 追加したい処理 6
  • 7. Joinpoint •  Adviceを追加できるとき(ポイント) •  AOPの仕様であり、実装者は変更できない •  Joinpointの仕様例 ‒  メソッドの開始時、終了時 ‒  プロパティが利用されたとき DaoImpl add() delete() find() update() Joinpoint 例:メソッドの開始時や終了時 7
  • 8. Pointcut •  Joinpointに達した命令を、Adviceまで到 達させるか否かフィルタリングするフィ ルター Joinpointを条件「add*」で絞り込む DaoImpl Pointcut add() delete() Advice ServiceImpl find() Dao update() Joinpoint 追加したい処理 8
  • 9. Befor Advice •  Joinpointの前で実行される メソッドの実行前に割り込む method() Before Advice Client Servant return Exception 9
  • 10. After Advice •  Joinpointの後で実行される method() Client Servant After Advice return Exception メソッドの実行後に割り込む 10
  • 11. After Returning Advice •  Joinpointが正常終了した後に実行される method() return Client After Returning Advice Servant Exception メソッドの実行後に正常終了時 に割り込む 11
  • 12. Around Advice •  Joinpointの前後で実行される method() method() Client Around Advice return Servant Exception メソッドの実行前と実行後、例 外発生時にも割り込む 12
  • 13. Throw Advice •  Joinpointで例外が発生した時に実行される method() Client Servant return Throw Advice Exception 例外発生時に割り 込む 13
  • 14. 問題 •  メソッドの開始と終了のログをとりた かったら? •  メソッドが正常終了したログをとりた かったら? •  メソッドが異常終了したときのログをと りたかったら? 14
  • 15. AOPの仕組み例 •  Proxyベースの場合、ProxyオブジェクトはSpringが自動生成する :Bean :Advice 処理の 処理の依頼 依頼 Adviceの呼び出し :Client :Proxy :Spring Interface 自動生成 Bean定義 Pointcutの参照 ファイル 1-15
  • 16. AOPの主な利用方法 •  各クラスに記述されている同一の処理を抜き出し、ひと まとめにして、既存のクラスに後から追加する ‒  ライブラリとの違い •  ライブラリは呼び出さないといけない •  AOPは勝手に追加される •  追加すると便利な処理 ‒  トランザクション管理 •  トランザクション管理は難しいくプログラマに任せられない ‒  ログ管理 •  メソッドの開始と終了のトレースログが正しく出力されない ‒  誰もフォーマットを守らない ‒  トレースログを追加し忘れる ‒  例外管理 •  処理の途中でExceptionが握りつぶされてしまう ‒  Exceptionを実行時例外にする 16
  • 17. AOPでやらない方が良いこと •  個別の処理(特定業務の処理、デバッ グ) ‒  プログラマが個別にAOPをいれるのは不可 •  そこで何をやっているのかが分からなくなる •  業務アプリのプログラマではなく、基盤 チームとかが使う技術!? 17
  • 18. SpringのAOP •  定義ファイルの利用 ‒  Spring1.x系では基本 •  アノテーションの利用 ‒  Spring2.x系以降、アノテーションの利用が増 えている(大規模開発や大手SI便だでは定義 ファイルの利用が多い) 18
  • 19. 問題 書いてないけど? •  例えば ‒  アノテーション •  メリット:定義ファイルの管理が不要 •  デメリット:プログラマにアノテーションを意識 ‒  とか、定義ファイルのメリットとかデメリット 19
  • 21. アスペクトの例 •  アノテーションの利用 @Aspect public class AspectMessage { @After("execution(* exMethod())") public void hoge() { // メソッド終了後に動くAdvice System.out.println("after called"); } } 21
  • 22. アノテーション一覧 •  アノテーションを利用したAOP ‒  Bean定義ファイルの記述が簡潔になる ‒  ソースコードに記述することで管理が煩雑 アノテーション 説明 @Aspect Adviceとなるクラスを指定するアノテーション @Around Around Adviceとなるメソッドを指定するアノテーション @Before Before Adviceとなるメソッドを指定するアノテーション @After After Adviceとなるメソッドを指定するアノテーション @AfterReturning After Returning Adviceとなるメソッドを指定するアノテーション @AfterThrowing After Throwing Adviceとなるメソッドを指定するアノテーション 22
  • 23. アドバイス詳細(1) •  Before, After ‒  @After( Primitiveポイントカット ) •  メソッド名は任意、メソッドのパラメータと戻り値はなしでも可能。 メソッド内で、アスペクト対象となっているメソッド名やパラメー タ,戻り値などの取得をする場合は、パラメータにJoinPoint •  メソッド内で、アスペクト対象となっているメソッドを呼び出す必 要はない @Before(“execution(* exMethod())”) public void hoge() { ・・・ } 23
  • 24. アドバイス詳細(2) •  Around ‒  @Around( Primitiveポイントカット ) •  メソッド名は任意、メソッドのパラメータには必 ずProceedingJoinPointが必要、戻り値はアスペ クト対象のメソッドにあわせる •  メソッド内で、アスペクト対象となっているメ ソッドを呼び出す必要がある ‒  ProceedingJoinPoint#proceed()メソッド »  Object proceed() throws Trowable •  メソッド内で、アスペクト対象となっているメ ソッド名やメソッドのパラメータの取得は ProceedingJoinPointを介しておこなう 24
  • 25. アドバイス詳細(3) •  Around ‒  戻り値はアスペクト対象にあわせる public String getMessage() { return “hello!”; アスペクト対象のメソッド } @Around(“execution(* getMessage())”) public String fuga(ProceedingJoinPoint pjp) throws Throwable {; String msg = (String)pjp.proceed(); return msg; } 25
  • 26. アドバイス詳細(4) public int getFigure() { return 100; アスペクト対象のメソッド } @Around(“execution(* getFigure())”) public int fuga(ProceedingJoinPoint pjp) throws Throwable {; Integer figure= (Integer)pjp.proceed(); return figure.intValue(); } 26
  • 27. アドバイス詳細(5) •  Around ‒  ProceedingJoinPointの使い方 メソッド名の取得 Signature sig = pjp.getSignature(); System.out.println("Sig: " + sig.getName()); パラメータの取得(最初のパラメータ) Object[] os = pjp.getArgs(); System.out.println("Args: " + os[0]); 27
  • 28. 問題∼重複してたらどうなる? @Around(“execution(* add())”) public int hoge (ProceedingJoinPoint pjp) throws Throwable {; Integer figure= (Integer)pjp.proceed(); return figure.intValue(); これと同じhogehogeメソッド } が存在したら? private int x; public int add(int i) { x = x + i; アスペクト対象のメソッド return x; } 28
  • 29. アドバイス詳細(6) •  AfterReturning ‒  @AfterReturning(value= Primitiveポイント カット , returnig = 戻り値の変数名 ) •  メソッド名は任意、メソッドのパラメータはアス ペクト対象となっているメソッドの戻り型とアノ テーションのretuning属性で指定した変数名 •  メソッド内で、アスペクト対象となっているメ ソッドを呼び出す必要はない 29
  • 30. アドバイス詳細(7) public String exMethod() { return “hello!”; アスペクト対象のメソッド } @AfterReturning(value=“execution(* exMethod())”, returning=“ret”) public String hoge(String ret) { System.out.println(“Return: “ + ret); } 30
  • 31. アドバイス詳細(8) •  AfterThrowing ‒  @AfterReturning(value= Primitiveポイント カット , throwing = 例外の変数名 ) •  メソッド名は任意、メソッドのパラメータはアス ペクト対象となっているメソッドの戻り型とアノ テーションのthrowing属性で指定した変数名 •  メソッド内で、アスペクト対象となっているメ ソッドを呼び出す必要がない 31
  • 32. アドバイス詳細(9) @AfterThrowing(value=“execution(* exMethod())”,                               throwing=“ex”) public String foo(HogeException ex) { System.out.println(“Exception Msg: “ + ex.getMessage()); } 32
  • 33. アドバイス詳細(10) •  AfterThrowing @AfterThrowing(value=“execution(* exMethod())”, throwing=“ex”) public String foo(Throwable ex) { System.out.println(“Exception Msg: “ + ex.getMessage()); } @AfterThrowing(value=“execution(* exMethod()”, throwing=“ex”) public String var(HogeException ex) { System.out.println(“Exception Msg: “ + ex.getMessage()); } @AfterThrowing(value=“execution(* exMethod()”, throwing=“ex”) public String hoge(Exception ex) { System.out.println(“Exception Msg: “ + ex.getMessage()); } 33
  • 34. 問題∼どのアドバイス? •  前ページの実装があったとき、どこかの プログラムがExceptionを投げてよこしま した •  どのアドバイスが動くでしょう? 34
  • 35. Primitiveポイントカット Primitive ポイントカット 概要 execution 呼出先の「メソッド」、「コンストラクタ」を指定する。 within 呼出元の「クラス」を指定する。
 withinをPointcutに指定すると、指定されたクラスから呼出される、メソッ ド等が選択されることになる。
 対象は、指定されたクラスで宣言されたメソッドに限定され、指定された クラスの親クラスで宣言されたメソッド内は対象外となる。 this 呼出元の「クラス」を指定する。
 thisをPointcutに指定すると、指定されたクラスから呼出される、メソッド 等が選択されることになる。
 withinとは、親クラスで定義されたメソッドの呼出しも対象とする点が異な る。 target 呼出先の「クラス」を指定する。
 ただし、呼出先のstaticフィールドは対象外となる。 args 呼出先「メソッド」の引数の型を指定する。 ※Primitiveポイントカット:あらかじめ用意されているポイントカットのこと 35
  • 36. executionの基本構文 •  execution(メソッドの修飾子△メソッドの戻り値型△ パッケージ.クラスまたはインタフェース.メソッド名 (仮引数の型|,仮引数の型…|) △throws 例外) •  「メソッドの修飾子(publicやprivateは省略可能)」や 「throws△例外」は省略することが可能 •  メソッドの戻り値型、パッケージやクラス名、インタ フェース名にはワイルドカード(*)の利用が可能 •  仮引数に(..)を記述すると任意の個数の引数と一致さ せることが可能 36
  • 37. ポイントカットで利用できる論理演算子 論理 説明 演算子 || または 論理和を意味する論理演算子 or 例) execution(* *..AopExBean.exMethod()) or execution(* *..AopExBeanParent.exMethod())  →AopExBeanのメソッドexMethodまたはAopExBeanParentのメソッドexMethodを指定 && また 論理積を意味する論理演算子 は and 例) execution(* *..AopExBean.exMethod()) && execution(* *..AopExBeanParent.exMethod())  →AopExBeanのメソッドexMethodまたはAopExBeanParentのメソッドexMethodを指定 ! または 否定を意味する論理演算子。 not 例) execution(* exMethod()) and not execution(* *..AopExBeanParent.*())  →AopExBeanParent以外のクラス(インタフェース)のメソッドexMethodを指定 37
  • 38. コーディング例(1) @Aspect public class AspectMessage { @After("execution(* exMethod())") public void after() { // メソッド終了後に動作するAdvice System.out.println("after called"); } @Before("execution(* exMethod())") public void before() { // メソッド開始時に動作するAdvice System.out.println("before called"); } 38
  • 39. コーディング例(2) @Around("execution(* exMethod())") public void around(ProceedingJoinPoint pjp) throws Throwable { // メソッド呼出の前後に動作するAdvice System.out.println("pre proceed"); pjp.proceed(); System.out.println("post proceed"); } 39
  • 40. コーディング例(3) @AfterReturning(value="execution(* exMethod())", returning="ret") public void afterReturning(String ret) { // メソッド呼出が例外の送出なしに終了した際に動作するAdvice System.out.println("after returning called"); System.out.println("return value = " + ret); } @AfterThrowing(value="execution(* exMethod())", throwing="ex") public void afterThrowing(Throwable ex) { // メソッド呼出が例外の送出なしに終了した際に動作するAdvice System.out.println("after throwing called"); System.out.println("exception value = " + ex.toString()); } } 40
  • 41. 定義ファイル <?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 xmlns:aop=http://www.springframework.org/schema/aop 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 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> … <aop:aspectj-autoproxy/> … </beans> 41
  • 43. それでも書きたい定義ファイル(1) ・・・ <aop:config> <aop:aspect id="myAspect" ref="aspectMessage"> <aop:pointcut id="fuga" expression="execution(* getMessage())"/> <aop:before pointcut-ref="fuga" method="foo"/> <aop:after pointcut-ref="fuga" method="var"/> <aop:around pointcut-ref="fuga" method="hoge"/> </aop:aspect> </aop:config> 43
  • 44. それでも書きたい定義ファイル(2) <aop:config> <aop:aspect id="myAspect2" ref="aspectMessage2"> <aop:pointcut id="fuga2" expression="execution(* getMessage())"/> <aop:after pointcut-ref="fuga2" method="hoge"/> </aop:aspect> </aop:config> ・・・ <bean id="aspectMessage" class="sample.aop.AspectMsg" /> <bean id="aspectMessage2" class="sample.aop.AspectMsg2" /> ・・・ 44
  • 45. コーディング例 public class AspectMessage { public void after() { // メソッド終了後に動作するAdvice System.out.println("after called"); } public void before() { // メソッド開始時に動作するAdvice System.out.println("before called"); } ・・・以下省略 45
  • 46. 問題 消すことできる? <aop:config> <aop:aspect id="myAspect2" ref="aspectMessage2"> <aop:pointcut id="fuga2" expression="execution(* getMessage())"/> beanを定義している2行 <aop:after pointcut-ref="fuga2" method="hoge"/> </aop:aspect> </aop:config> ・・・ <bean id="aspectMessage2" class="sample.aop.AspectMsg2" /> <bean id="aspectMessage2" class="sample.aop.AspectMsg" /> ・・・ 46
  • 48. アーキテクチャ・リファクタリング(1/5) Employee Employee FindAction MySql RDB Service Dao ブラウザ •  表示と永続化のフレームワーク導入済 •  インタフェース未使用(もちろんDI,AOPも) ‒  チーム開発がしずらい ‒  変更、機能拡張、テストが容易ではない •  連続性も阻害 ‒  Conecctionの引き回し、検査時例外の伝搬 48
  • 49. アーキテクチャ・リファクタリング(2/5) インタフェースの導入 Employee Employee Service Dao <<Singleton>> <<Singleton>> FindAction Employee Employee MySQL ServiceImpl DaoMySql ブラウザ RDB 利用 利用 生成 生成 Factory •  メリット ‒  インタフェースを区切りとして、チーム開発がやりやすくなった ‒  変更、機能拡張、テストが容易になった •  デメリット ‒  Factoryを実装する必要がある ‒  クラスはFactoryに依存する 49
  • 50. アーキテクチャ・リファクタリング(3/5) DIの導入 Employee Employee Service Dao Employee Employee FindAction MySQL ServiceImpl DaoMySql ブラウザ RDB 生成 生成 Injection Injection DIコンテナ •  Factoryを実装する必要がない •  クラスはDIコンテナに依存しない 50
  • 51. アーキテクチャ・リファクタリング(4/5) DIコンテナ導入後のソースコード •  トランザクション管理やログ出力、例外処理が残っている Employee ‒  分岐が多いため、テストの量が多くなる ServiceImpl ‒  共通化できる部分が隠蔽できていない ‒  例外処理とConnectionの引き渡しによる連続性の阻害がある public class EmployeeServiceImpl" } catch(Exception e) {! implements EmployeeService{" conn.rollback();! @Autowired! ・・・ private EmployeeDao dao;" } finally {! ・・・ conn.close();!  public List findAll() throws Exception {! ・・・ if(Log.flag) { System.out.println(“***Start”); }! }! Connection conn = null;" if(Log.flag) { System.out.println(“***End”); }" ・・・ return employeeList;" //EmployeeDao dao ! }" // = (EmployeeDao)Factory.create(KEY);! ・・・ List employeeList = null;" try {" employeeList = dao.findAll(conn);" conn.commit();! 51
  • 52. アーキテクチャ・リファクタリング(5/5) AOP導入後のソースコード •  共通ライブラリを廃止してAOPを導入 •  連続性の確保 ‒  トランザクション管理、ログ出力、例外処理はAOPで実現しているため、ソースコード上から はなくなっている ‒  Advice実装されており、なくなっている訳ではない •  ソースコードの記述量が減り、バグの数も低下、開発者の作業も軽減 •  テストの容易性も向上 public class EmployeeServiceImpl ! 書くことがなくなりました・・・! implements EmploeeService {! @Autowired! private EmployeeDao dao;!   public List findAll() {! return dao.findAll();! }! ・・・ 52
  • 53. アーキテクチャ・リファクタリングの嘘 •  AOPで業務例外(例えば、在庫がなかった時に どうする)は処理できないから、そんなに奇麗 に例外は消えない(多分…) •  だって、AOPを使う基盤チームは業務を知らな い(多分…)。だから、業務例外はAOPで提供 できない •  それに業務例外がAOPになったら、業務プログ ラムが読めない! •  そもそも、業務例外にExceptionを使うのって どうよ(!?)という問題でもある 53
  • 55. Spring MVCとは •  Spring Frameworkに含まれるWeb MVCフレームワーク ‒  初期のSpring Frameworkの段階から含まれ ている ‒  StrutsやJSFと競合 •  特徴 ‒  DIコンテナとの親和性 ‒  きれいな設計 •  インタフェースを使用して部品化 55
  • 56. Spring MVCのController DIの導入 Employee Employee Service Dao Employee Employee XxxController MySQL ServiceImpl DaoMySql ブラウザ RDB 生成 生成 生成 Injection Injection DIコンテナ 56
  • 57. 難しいと評判(?)のSpring MVC •  Spring1.xのSpring MVC ‒  設定が難しい ‒  作り方がよくわからない ‒  日本語の情報が少ない ‒  そもそも知らない 57
  • 58. 簡単になったSpring MVC •  Spring 3.xのSpring MVC ‒  Springの新機能を導入 •  アノテーションにより設定がシンプルになり、わ かりやすくなった •  component-scanにより設定ファイルが最低限で すむようになった ‒  あいかわらず日本語の情報は少ない •  英語のマニュアルを読みましょう 58
  • 59. デモ •  STS(SpringSource Tool Suite)で作成 1.  メニューからNew->Project 2.  SpringSource Tool Suite->Spring Template Projectを選択 3.  Spring MVC Projectを選択 59
  • 60. 動作概要 <<controller>> Model HomeController "serverTime" Date home() ③ (現在の日時) Dispatcher ブラウザ ① Servlet (ほか色々) <<jsp>> /WEB-INF/views/home.jsp ⑥ 60
  • 61. HomeController DIコンテナにより 自動で読み込まれる (component-scan) HTTPメソッドがGETで @Controller 「/」へアクセスした際に public class HomeController { 実行される @RequestMapping(value = "/", method = GET) public String home(Model model) { Viewに渡したいオブジェクトを Date date = new Date(); 設定する model.addAttribute("serverTime", date); return "home"; } View名をreturnする } ※少し手を加えシンプルにしています 61
  • 62. home.jsp <html> <head> <title>Home</title> Modelに設定したオブジェクトは </head> 自動的にHttpServletRequestに 設定されている <body> <h1>Hello world! </h1> <p>The time on the server is ${serverTime}.</p> </body> </html> ※少し手を加えシンプルにしています 62
  • 63. @RequestMapping色々 // 一つのメソッドに複数のURLを割り当て @RequestMapping({"/", "/home"}) public String home() { ・・・ // 一つのURLでHTTPメソッドごとにメソッドを切り分け @RequestMapping(value="/foo", method=GET) public String doGetMethod() { ・・・ @RequestMapping(value="/foo", method=POST) public String doPostMethod() { ・・・ 63
  • 64. 引数色々① // リクエストパラメータを取得(「/person?id=10」などでアクセス) @RequestMapping(value = "/person", method=GET) public String showPerson1 ( @RequestParam("id") int id, Model model) { Person person = findById(id); model.addAttribute("person", person); ・・・ // URLの値を取得(「/person/10」などでアクセス) @RequestMapping(value = "/person/{id}", method=GET) public String showPerson2( @PathVariable("id") int id, Model model) { Person person = findById(id); model.addAttribute("person", person); ・・・ 64
  • 65. 引数色々② // 画面からの入力をマッピング(formからデータを送信) @RequestMapping(value = "/person", method = POST) public String registerPerson(@ModelAttribute Person person) { register(person); ・・・ // ほかにも色々 @RequestMapping("/foo") public String foo( Model model, WebRequest req, WebResponse res, Cookie cookie, Locale locale, HttpServletRequest sreq, HttpServletResponse sres) { ・・・ 65
  • 66. その他の機能 •  Session管理 ‒  @SessionAttributes(model名)をクラスに設定すると、Modelに追加 したオブジェクトはHttpSessionに追加される ‒  @ModelAttribute(model名)を引数に設定すると、Sessionのオブジェ クトが引数に渡される ‒  SessionStatus#setComplete()でHttpSession内のオブジェクトが破 棄される •  ControllerごとにSession内のオブジェクトを管理可能 •  入力チェック(Validation) ‒  JSR-303(Bean Validation)に対応 •  @NotNull String id; •  @Length(max = 30) String name; ‒  Validation対象の引数に@Validを設定する •  例外処理 ‒  例外発生時に実行するメソッドに@ExceptionHandler (FooException.class) 66