Spring-MVC/ステップ・バイ・ステップ/AopNameSpaceを使う
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
[[Spring-MVC/ステップ・バイ・ステップ]]
2008/04/16からのアクセス回数 &counter;
#contents
** AopNameSpaceとは何か [#z558866b]
Spring 2.0の特徴は、
- NameSpaceを使ってAOPやトランザクションの記述が簡単にで...
- AspectJをサポートした
ことです。
AopNameSpaceでは、普通のオブジェクト(以下POJOオブジェク...
Adviceとして使用することができます。
''AopNameSpaceを使用するとAutoProxyCreatorは使用できない...
** 準備 [#c1b26fc9]
AopNameSpaceを使用するには、
- spring.jar(version 2.5以降)
- aspectjrt.jar(version 1.5以降)
- aspectjweaver.jar(version 1.5以降)
が必要です。
いつものようにMVN Repositoryで検索すると、以下のようなdep...
#pre{{
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.4</version>
</dependency>
}}
これをpom.xmlに追加して、以下のコマンドを実行してください。
#pre{{
$ rm .project .classpath
$ mvn eclipse:eclipse -DdownloadSources=true
}}
** AopNameSpaceの例題 [#uee1662d]
AopNameSpaceを使った例を順を追って作成していきましょう。
*** POJOオブジェクト [#g5e1af53]
Adviceとして使用するPOJOオブジェクトクラス(POJOAdvice)...
#pre{{
package org.springframework.showcase.aop;
public class POJOAdvice {
public void a() {
System.out.println("a called");
}
public void b(Long id) {
System.out.println("b(" + id +") called");
}
}
}}
- aは単に”a called”と出力します
- bは、引数にidを持ち、"b(id) called"と出力します
*** AOP定義ファイル [#m435ea61]
AopNameSpaceを使った定義ファイルは他のBean定義ファイルと...
機能が切り分けられます。
aop-def.xmlは、以下のようになります。
#pre{{
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/sc...
http://www.springframework.org/schema/beans/spring-bean...
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2....
<bean id="pojoAdvice" class="org.springframework.show...
<aop:config>
<aop:aspect ref="pojoAdvice">
<aop:before
method="a"
pointcut="execution(* *.findAll(..))" />
<aop:before
method="b"
pointcut="execution(* org.springframework...
and args(id)"
/>
</aop:aspect>
</aop:config>
</beans>
}}
- beans定義では、AopNameSpaceを使用するためにNameSpaceを...
- pojoAdviceがPOJOAdviceのBeanです
- <aop:config>がAOPの定義を示します
- <aop:aspect>のrefでpojoAdviceを指定します
- <aop:before>でpojoAdviceの呼び出すメソッド名とpointcut...
'<aop:config>では、<aop:before>の他に以下の要素(タグ)が...
| 要素名 | 目的 |
| <aop:advisor> | AOP Advisorを定義します |
| <aop:after> | AOP after advice を定義します(正常・異常...
| <aop:after-returning> | AOP after-return adivice を定義...
| <aop:after-throwing> | AOP after-throwing advice を定義...
| <aop:around> | AOP around advice を定義します |
| <aop:aspect> | aspectを定義します|
| <aop:before> | AOP before advice を定義します |
| <aop:pointcut> | pointcut を定義します |
'<aop:before>に戻って
- method: aというメソッドを呼び出すことを指定
- pointcut: AspectJの記述形式でpointcutを指定
します。
AspectJのpointcutは、
execution ( <戻り値のタイプ> <クラスパス>.<メソッド名>( ...
の形式で記述します。
aの場合のpointcutを見てみると
#pre{{
pointcut="execution(* *.findAll(..))"
}}
とありますが、型、クラスパスに関係なくfindAllという名前の...
指定です。
次にbの場合のpointcutを見ると
#pre{{
pointcut="execution(* org.springframework.showcase.coverc...
and args(id)"
}}
and args(id)でfindByIdの引数idをbの呼び出しに渡すことを指...
*** web.xmlの変更 [#j0994e68]
aop-def.xmlを追加するために、web.xmlに以下のcontext-param...
#pre{{
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
/WEB-INF/aop-def.xml
</param-value>
</context-param>
}}
*** applicationContext.xmlの変更 [#m6eb002c]
前回のDefaultAdvisorAutoProxyCreatorを使ったAOPと共存でき...
以下のように変更します。
#pre{{
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-...
<beans>
<bean id="recipeManager" class="org.springframework.show...
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManage...
<property name="driverClassName">
<value>org.postgresql.Driver</value>
</property>
<property name="url">
<value>jdbc:postgresql://localhost/springdb</value>
</property>
<property name="username">
<value>spring</value>
</property>
<property name="password">
<value>spring</value>
</property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionF...
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Po...
</props>
</property>
<property name="mappingDirectoryLocations">
<list>
<value>classpath:/org/springframework/showcase/coverc...
</list>
</property>
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
</beans>
}}
** 例題の実行 [#mb38416e]
maven jettyプラグインを使って例題を実行します。
#pre{{
$ mvn jetty:run
}}
次にブラウザーで
http://localhost:8080/mvc-convention/
と入力すると
#pre{{
a called
a called
}}
と表示されます。これは、RecipeManagerのfindAllとGenericHi...
pointcutが設定されたからです。
次に、ブラウザのaddリンクをクリックして「test」を入力した...
testがリストに追加されましたが、testのdeleteリンクをクリ...
#pre{{
b(4) called
a called
a called
}}
とb(4) calledが表示されます。bは、
org.springframework.showcase.coverc.service.GenericHiber...
とクラスパスを指定しているので1回だけ表示されます。
** ログ出力との併用 [#ne4e3c45]
AopNameSpaceを使ったAOPでは、引数を明示的に指定する必要が...
チェックプリントのメソッドを実行することができません。
チェックプリントは、デバッガでは追えない並行処理のデバッ...
ここでは、ログ出力とAopNameSpaceの併用の方法について説明...
チェックプリントを出力したいBeanをProxyFactoryBeanでラッ...
指定したBeanにログ出力機能を加えることができます。
- logBaseでinterceptorNames属性を定義します
- recipeManagerをStubRecipeDaoManagerからProxyFactoryBean...
- ProxyFactoryBeanのtargetにStubRecipeDaoManagerのBeanを...
#pre{{
<bean id="enterMethodLogAdvice" class="org.springframewo...
<bean id="leaveMethodLogAdvice" class="org.springframewo...
<bean id="logBase" abstract="true">
<property name="interceptorNames">
<list>
<value>enterMethodLogAdvice</value>
<value>leaveMethodLogAdvice</value>
</list>
</property>
</bean>
<bean id="recipeManager" class="org.springframework.aop....
parent="logBase">
<property name="target">
<bean class="org.springframework.showcase.coverc.servi...
<property name="sessionFactory" ref="sessionFactory" ...
</bean>
</property>
</bean>
}}
*** 実行例 [#w5dd437d]
先ほどと同様に実行すると、
#pre{{
a called
enter findAll args=()
a called
leave findAll return=[org.springframework.showcase.coverc...
org.springframework.showcase.coverc.domain.Recipe@a06db5,
org.springframework.showcase.coverc.domain.Recipe@82aacf]
-- 途中省略
enter save args=(org.springframework.showcase.coverc.doma...
leave save return=null
a called
enter findAll args=()
a called
leave findAll return=[org.springframework.showcase.coverc...
org.springframework.showcase.coverc.domain.Recipe@cdb92b,
org.springframework.showcase.coverc.domain.Recipe@37bc9e,
org.springframework.showcase.coverc.domain.Recipe@403477]
enter findById args=(4)
b(4) called
leave findById return=org.springframework.showcase.coverc...
enter delete args=(org.springframework.showcase.coverc.do...
leave delete return=null
a called
enter findAll args=()
a called
leave findAll return=[org.springframework.showcase.coverc...
org.springframework.showcase.coverc.domain.Recipe@7ec7b9,
org.springframework.showcase.coverc.domain.Recipe@6a56f0]
}}
のようにログ出力とAopNameSpaceの出力の両方が出ています。
[[Spring-MVC/ステップ・バイ・ステップ/AOPの追加]]の
今回使用したファイルは、以下にあります。
#ref(aop-def.xml);
#ref(applicationContext.xml);
#ref(web.xml);
#ref(POJOAdvice.java);
** コメント [#n9849984]
この記事は、
#vote(おもしろかった,そうでもない,わかりずらい)
皆様のご意見、ご希望をお待ちしております。
#comment_kcaptcha
終了行:
[[Spring-MVC/ステップ・バイ・ステップ]]
2008/04/16からのアクセス回数 &counter;
#contents
** AopNameSpaceとは何か [#z558866b]
Spring 2.0の特徴は、
- NameSpaceを使ってAOPやトランザクションの記述が簡単にで...
- AspectJをサポートした
ことです。
AopNameSpaceでは、普通のオブジェクト(以下POJOオブジェク...
Adviceとして使用することができます。
''AopNameSpaceを使用するとAutoProxyCreatorは使用できない...
** 準備 [#c1b26fc9]
AopNameSpaceを使用するには、
- spring.jar(version 2.5以降)
- aspectjrt.jar(version 1.5以降)
- aspectjweaver.jar(version 1.5以降)
が必要です。
いつものようにMVN Repositoryで検索すると、以下のようなdep...
#pre{{
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.4</version>
</dependency>
}}
これをpom.xmlに追加して、以下のコマンドを実行してください。
#pre{{
$ rm .project .classpath
$ mvn eclipse:eclipse -DdownloadSources=true
}}
** AopNameSpaceの例題 [#uee1662d]
AopNameSpaceを使った例を順を追って作成していきましょう。
*** POJOオブジェクト [#g5e1af53]
Adviceとして使用するPOJOオブジェクトクラス(POJOAdvice)...
#pre{{
package org.springframework.showcase.aop;
public class POJOAdvice {
public void a() {
System.out.println("a called");
}
public void b(Long id) {
System.out.println("b(" + id +") called");
}
}
}}
- aは単に”a called”と出力します
- bは、引数にidを持ち、"b(id) called"と出力します
*** AOP定義ファイル [#m435ea61]
AopNameSpaceを使った定義ファイルは他のBean定義ファイルと...
機能が切り分けられます。
aop-def.xmlは、以下のようになります。
#pre{{
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/sc...
http://www.springframework.org/schema/beans/spring-bean...
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2....
<bean id="pojoAdvice" class="org.springframework.show...
<aop:config>
<aop:aspect ref="pojoAdvice">
<aop:before
method="a"
pointcut="execution(* *.findAll(..))" />
<aop:before
method="b"
pointcut="execution(* org.springframework...
and args(id)"
/>
</aop:aspect>
</aop:config>
</beans>
}}
- beans定義では、AopNameSpaceを使用するためにNameSpaceを...
- pojoAdviceがPOJOAdviceのBeanです
- <aop:config>がAOPの定義を示します
- <aop:aspect>のrefでpojoAdviceを指定します
- <aop:before>でpojoAdviceの呼び出すメソッド名とpointcut...
'<aop:config>では、<aop:before>の他に以下の要素(タグ)が...
| 要素名 | 目的 |
| <aop:advisor> | AOP Advisorを定義します |
| <aop:after> | AOP after advice を定義します(正常・異常...
| <aop:after-returning> | AOP after-return adivice を定義...
| <aop:after-throwing> | AOP after-throwing advice を定義...
| <aop:around> | AOP around advice を定義します |
| <aop:aspect> | aspectを定義します|
| <aop:before> | AOP before advice を定義します |
| <aop:pointcut> | pointcut を定義します |
'<aop:before>に戻って
- method: aというメソッドを呼び出すことを指定
- pointcut: AspectJの記述形式でpointcutを指定
します。
AspectJのpointcutは、
execution ( <戻り値のタイプ> <クラスパス>.<メソッド名>( ...
の形式で記述します。
aの場合のpointcutを見てみると
#pre{{
pointcut="execution(* *.findAll(..))"
}}
とありますが、型、クラスパスに関係なくfindAllという名前の...
指定です。
次にbの場合のpointcutを見ると
#pre{{
pointcut="execution(* org.springframework.showcase.coverc...
and args(id)"
}}
and args(id)でfindByIdの引数idをbの呼び出しに渡すことを指...
*** web.xmlの変更 [#j0994e68]
aop-def.xmlを追加するために、web.xmlに以下のcontext-param...
#pre{{
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
/WEB-INF/aop-def.xml
</param-value>
</context-param>
}}
*** applicationContext.xmlの変更 [#m6eb002c]
前回のDefaultAdvisorAutoProxyCreatorを使ったAOPと共存でき...
以下のように変更します。
#pre{{
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-...
<beans>
<bean id="recipeManager" class="org.springframework.show...
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManage...
<property name="driverClassName">
<value>org.postgresql.Driver</value>
</property>
<property name="url">
<value>jdbc:postgresql://localhost/springdb</value>
</property>
<property name="username">
<value>spring</value>
</property>
<property name="password">
<value>spring</value>
</property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionF...
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Po...
</props>
</property>
<property name="mappingDirectoryLocations">
<list>
<value>classpath:/org/springframework/showcase/coverc...
</list>
</property>
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
</beans>
}}
** 例題の実行 [#mb38416e]
maven jettyプラグインを使って例題を実行します。
#pre{{
$ mvn jetty:run
}}
次にブラウザーで
http://localhost:8080/mvc-convention/
と入力すると
#pre{{
a called
a called
}}
と表示されます。これは、RecipeManagerのfindAllとGenericHi...
pointcutが設定されたからです。
次に、ブラウザのaddリンクをクリックして「test」を入力した...
testがリストに追加されましたが、testのdeleteリンクをクリ...
#pre{{
b(4) called
a called
a called
}}
とb(4) calledが表示されます。bは、
org.springframework.showcase.coverc.service.GenericHiber...
とクラスパスを指定しているので1回だけ表示されます。
** ログ出力との併用 [#ne4e3c45]
AopNameSpaceを使ったAOPでは、引数を明示的に指定する必要が...
チェックプリントのメソッドを実行することができません。
チェックプリントは、デバッガでは追えない並行処理のデバッ...
ここでは、ログ出力とAopNameSpaceの併用の方法について説明...
チェックプリントを出力したいBeanをProxyFactoryBeanでラッ...
指定したBeanにログ出力機能を加えることができます。
- logBaseでinterceptorNames属性を定義します
- recipeManagerをStubRecipeDaoManagerからProxyFactoryBean...
- ProxyFactoryBeanのtargetにStubRecipeDaoManagerのBeanを...
#pre{{
<bean id="enterMethodLogAdvice" class="org.springframewo...
<bean id="leaveMethodLogAdvice" class="org.springframewo...
<bean id="logBase" abstract="true">
<property name="interceptorNames">
<list>
<value>enterMethodLogAdvice</value>
<value>leaveMethodLogAdvice</value>
</list>
</property>
</bean>
<bean id="recipeManager" class="org.springframework.aop....
parent="logBase">
<property name="target">
<bean class="org.springframework.showcase.coverc.servi...
<property name="sessionFactory" ref="sessionFactory" ...
</bean>
</property>
</bean>
}}
*** 実行例 [#w5dd437d]
先ほどと同様に実行すると、
#pre{{
a called
enter findAll args=()
a called
leave findAll return=[org.springframework.showcase.coverc...
org.springframework.showcase.coverc.domain.Recipe@a06db5,
org.springframework.showcase.coverc.domain.Recipe@82aacf]
-- 途中省略
enter save args=(org.springframework.showcase.coverc.doma...
leave save return=null
a called
enter findAll args=()
a called
leave findAll return=[org.springframework.showcase.coverc...
org.springframework.showcase.coverc.domain.Recipe@cdb92b,
org.springframework.showcase.coverc.domain.Recipe@37bc9e,
org.springframework.showcase.coverc.domain.Recipe@403477]
enter findById args=(4)
b(4) called
leave findById return=org.springframework.showcase.coverc...
enter delete args=(org.springframework.showcase.coverc.do...
leave delete return=null
a called
enter findAll args=()
a called
leave findAll return=[org.springframework.showcase.coverc...
org.springframework.showcase.coverc.domain.Recipe@7ec7b9,
org.springframework.showcase.coverc.domain.Recipe@6a56f0]
}}
のようにログ出力とAopNameSpaceの出力の両方が出ています。
[[Spring-MVC/ステップ・バイ・ステップ/AOPの追加]]の
今回使用したファイルは、以下にあります。
#ref(aop-def.xml);
#ref(applicationContext.xml);
#ref(web.xml);
#ref(POJOAdvice.java);
** コメント [#n9849984]
この記事は、
#vote(おもしろかった,そうでもない,わかりずらい)
皆様のご意見、ご希望をお待ちしております。
#comment_kcaptcha
ページ名:
SmartDoc