Spring-schema-based-aop-appoach
Springを使用したXMLスキーマベースのAOP
このセクションで説明されているAOP名前空間タグを使用するには、説明されているようにspringAOPスキーマをインポートする必要があります-
<?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:aop = "http://www.springframework.org/schema/aop"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<!-- bean definition & AOP specific configuration -->
</beans>
また、アプリケーションのCLASSPATHに次のAspectJライブラリが必要です。 これらのライブラリは、AspectJインストールの「lib」ディレクトリにあります。それ以外の場合は、インターネットからダウンロードできます。
- aspectjrt.jar
- aspectjweaver.jar
- aspectj.jar
- aopalliance.jar
アスペクトを宣言する
*aspect* は *<aop:aspect>* 要素を使用して宣言され、バッキングBeanは次のように *ref* 属性を使用して参照されます-
<aop:config>
<aop:aspect id = "myAspect" ref = "aBean">
...
</aop:aspect>
</aop:config>
<bean id = "aBean" class = "...">
...
</bean>
ここでは、前の章で見たように、他のSpring Beanと同じように「aBean」が構成され、依存関係が注入されます。
ポイントカットを宣言する
*pointcut* は、さまざまなアドバイスで実行する対象の結合ポイント(つまりメソッド)を決定するのに役立ちます。 XMLスキーマベースの構成で作業中、ポイントカットは次のように定義されます-
<aop:config>
<aop:aspect id = "myAspect" ref = "aBean">
<aop:pointcut id = "businessService"
expression = "execution(*com.xyz.myapp.service.*.*(..))"/>
...
</aop:aspect>
</aop:config>
<bean id = "aBean" class = "...">
...
</bean>
次の例では、com.finddevguidesパッケージの下のStudentクラスで使用可能なgetName()メソッドの実行と一致する「businessService」という名前のポイントカットを定義しています。
<aop:config>
<aop:aspect id = "myAspect" ref = "aBean">
<aop:pointcut id = "businessService"
expression = "execution(*com.finddevguides.Student.getName(..))"/>
...
</aop:aspect>
</aop:config>
<bean id = "aBean" class = "...">
...
</bean>
アドバイスを宣言する
次のように<aop:\ {ADVICE NAME}>要素を使用して、<aop:aspect>内で5つのアドバイスのいずれかを宣言できます-
<aop:config>
<aop:aspect id = "myAspect" ref = "aBean">
<aop:pointcut id = "businessService"
expression = "execution(* com.xyz.myapp.service.*.*(..))"/>
<!-- a before advice definition -->
<aop:before pointcut-ref = "businessService" method = "doRequiredTask"/>
<!-- an after advice definition -->
<aop:after pointcut-ref = "businessService" method = "doRequiredTask"/>
<!-- an after-returning advice definition -->
<!--The doRequiredTask method must have parameter named retVal -->
<aop:after-returning pointcut-ref = "businessService"
returning = "retVal" method = "doRequiredTask"/>
<!-- an after-throwing advice definition -->
<!--The doRequiredTask method must have parameter named ex -->
<aop:after-throwing pointcut-ref = "businessService"
throwing = "ex" method = "doRequiredTask"/>
<!-- an around advice definition -->
<aop:around pointcut-ref = "businessService" method = "doRequiredTask"/>
...
</aop:aspect>
</aop:config>
<bean id = "aBean" class = "...">
...
</bean>
同じ doRequiredTask または異なるアドバイスに異なるメソッドを使用できます。 これらのメソッドは、アスペクトモジュールの一部として定義されます。
XMLスキーマベースのAOPの例
XMLスキーマベースのAOPに関連する上記の概念を理解するために、いくつかのアドバイスを実装する例を作成しましょう。 少しアドバイスをしてサンプルを作成するには、動作するEclipse IDEを用意し、次の手順を実行してSpringアプリケーションを作成します。
Step | Description |
---|---|
1 | Create a project with a name SpringExample and create a package com.finddevguides under the *src *folder in the created project. |
2 | Add required Spring libraries using Add External JARs option as explained in the Spring Hello World Example chapter. |
3 | Add Spring AOP specific libraries* aspectjrt.jar, aspectjweaver.jar and aspectj.jar *in the project. |
4 | Create Java classes* Logging*, Student and MainApp under the com.finddevguides package. |
5 | Create Beans configuration file Beans.xml under the src folder. |
6 | The final step is to create the content of all the Java files and Bean Configuration file and run the application as explained below. |
*Logging.java* ファイルの内容は次のとおりです。 これは実際には、さまざまなポイントで呼び出されるメソッドを定義するアスペクトモジュールのサンプルです。
package com.finddevguides;
public class Logging {
/* *
* This is the method which I would like to execute
*before a selected method execution.
*/
public void beforeAdvice(){
System.out.println("Going to setup student profile.");
}
/* *
* This is the method which I would like to execute
*after a selected method execution.
*/
public void afterAdvice(){
System.out.println("Student profile has been setup.");
}
/* *
* This is the method which I would like to execute
*when any method returns.
*/
public void afterReturningAdvice(Object retVal) {
System.out.println("Returning:" + retVal.toString() );
}
/**
*This is the method which I would like to execute
* if there is an exception raised.
*/
public void AfterThrowingAdvice(IllegalArgumentException ex){
System.out.println("There has been an exception: " + ex.toString());
}
}
以下は Student.java ファイルの内容です
package com.finddevguides;
public class Student {
private Integer age;
private String name;
public void setAge(Integer age) {
this.age = age;
}
public Integer getAge() {
System.out.println("Age : " + age );
return age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
System.out.println("Name : " + name );
return name;
}
public void printThrowException(){
System.out.println("Exception raised");
throw new IllegalArgumentException();
}
}
以下は MainApp.java ファイルの内容です
package com.finddevguides;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
Student student = (Student) context.getBean("student");
student.getName();
student.getAge();
student.printThrowException();
}
}
以下は設定ファイル Beans.xml です
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop = "http://www.springframework.org/schema/aop"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<aop:config>
<aop:aspect id = "log" ref = "logging">
<aop:pointcut id = "selectAll"
expression = "execution(* com.finddevguides.*.*(..))"/>
<aop:before pointcut-ref = "selectAll" method = "beforeAdvice"/>
<aop:after pointcut-ref = "selectAll" method = "afterAdvice"/>
<aop:after-returning pointcut-ref = "selectAll"
returning = "retVal" method = "afterReturningAdvice"/>
<aop:after-throwing pointcut-ref = "selectAll"
throwing = "ex" method = "AfterThrowingAdvice"/>
</aop:aspect>
</aop:config>
<!-- Definition for student bean -->
<bean id = "student" class = "com.finddevguides.Student">
<property name = "name" value = "Zara"/>
<property name = "age" value = "11"/>
</bean>
<!-- Definition for logging aspect -->
<bean id = "logging" class = "com.finddevguides.Logging"/>
</beans>
ソースおよびBean構成ファイルの作成が完了したら、アプリケーションを実行しましょう。 すべてがあなたのアプリケーションでうまくいけば、それは次のメッセージを印刷します-
Going to setup student profile.
Name : Zara
Student profile has been setup.
Returning:Zara
Going to setup student profile.
Age : 11
Student profile has been setup.
Returning:11
Going to setup student profile.
Exception raised
Student profile has been setup.
There has been an exception: java.lang.IllegalArgumentException
.....
other exception content
上記で定義された<aop:pointcut>は、パッケージcom.finddevguidesで定義されたすべてのメソッドを選択します。 特定のメソッドの前後にアドバイスを実行したい場合、ポイントカット定義の星印(*)を実際のクラス名とメソッド名に置き換えることにより、ポイントカットを定義して実行を絞り込むことができます。 以下は、概念を示すために変更されたXML構成ファイルです-
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop = "http://www.springframework.org/schema/aop"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<aop:config>
<aop:aspect id = "log" ref = "logging">
<aop:pointcut id = "selectAll"
expression = "execution(* com.finddevguides.Student.getName(..))"/>
<aop:before pointcut-ref = "selectAll" method = "beforeAdvice"/>
<aop:after pointcut-ref = "selectAll" method = "afterAdvice"/>
</aop:aspect>
</aop:config>
<!-- Definition for student bean -->
<bean id = "student" class = "com.finddevguides.Student">
<property name = "name" value = "Zara"/>
<property name = "age" value = "11"/>
</bean>
<!-- Definition for logging aspect -->
<bean id = "logging" class = "com.finddevguides.Logging"/>
</beans>
これらの構成変更でサンプルアプリケーションを実行すると、次のメッセージが出力されます-
Going to setup student profile.
Name : Zara
Student profile has been setup.
Age : 11
Exception raised
.....
other exception content