English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Spring AOPの例

提供しました Spring1.2旧式のAOP (DTDに基づいて)実装された例です。

Springでは 3サポートされていますが、次のページで学ぶSpring AOPとAspectJの使用方法についてのアドバイスを次ページで学びます。

spring1.2旧式のAOP実装ではサポートされています。4の種類のAdviceがサポートされています。

Before Advice、実際のメソッド呼び出しの前に実行されます。 After Advice、実際のメソッド呼び出しの後で実行されます。メソッドが返値を持つ場合、その返値の後で実行されます。 Around Advice、実際のメソッド呼び出しの前後で実行されます。 Throws Advice、実際のメソッドが例外を発生させた場合、そのAdviceを実行します。

注意: Spring AOPの基本的な概念を理解するには、前のページを訪れてください。

Adviceの階層

以下の図を参照して、Adviceの階層を理解しましょう:

すべてはAOPのインターフェースです。

MethodBeforeAdvice インターフェースを拡張 BeforeAdvice インターフェース。

AfterReturningAdvice インターフェースを拡張 AfterAdvice インターフェース。

ThrowsAdvice インターフェースを拡張 AfterAdvice インターフェース。

MethodInterceptor インターフェースを拡張 Interceptor インターフェース。アドバイスの周りで使用されます。

1、MethodBeforeAdviceの例

実際のビジネスロジックを含むクラスを作成します。

ファイル: A.java

package com.w3codebox;
public class A {
public void m(){System.out.println("actual business logic");}
}

今度はMethodBeforeAdviceインターフェースを実装するアドバイザークラスを作成しましょう。

ファイル: BeforeAdvisor.java

package com.w3codebox;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class BeforeAdvisor implements MethodBeforeAdvice{
	@Override
	public void before(Method method, Object[] args, Object target) throws Throwable {
		System.out.println("実際のロジックの前に追加の関心");
	}
}

XMLファイル内で、以下のように作成します:3beanが3つあります。1つはAクラス用、2つ目はアドバイザークラス用、3つ目は ProxyFactoryBean クラス。

ファイル: applicationContext.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:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="obj" class="com.w3codebox.A"></bean>
<bean id="ba" class="com.w3codebox.BeforeAdvisor"></bean>
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="obj"></property>
<property name="interceptorNames">
<list>
<value>ba</value>
</list>
</property>
</bean>
</beans>

ProxyFactoryBeanクラスの理解:

ProxyFactoryBean このクラスはSpring Frameworkによって提供されています。以下を含んでいます:2属性targetとinterceptorNamesがあります。Aクラスのインスタンスはターゲットオブジェクトとして、アドバイザークラスのインスタンスはインターセプタとして見なされます。上記のXMLファイルのように、アドバイザーオブジェクトをリストオブジェクトとして渡す必要があります。

ProxyFactoryBeanクラスの記述は以下の通りです:

public class ProxyFactoryBean{
private Object target;
private List interceptorNames;
//getters and setters
}

今度は実際のメソッドを呼び出しましょう。

ファイル: Test.java

package com.w3codebox;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class Test {
public static void main(String[] args) {
	Resource r=new ClassPathResource("applicationContext.xml");
	BeanFactory factory=new XmlBeanFactory(r);
	A a=factory.getBean("proxy",A.class);
	a.m();
}
}

出力

実際のロジックの前に追加の心配
実際のビジネスロジック

MethodBeforeAdviceクラス内で他の情報を印刷することができます。例えば、メソッド名、メソッドパラメータ、ターゲットオブジェクト、ターゲットオブジェクトのクラス名、プロキシクラスなどです。

BeforeAdvisor.javaとTest.javaの2つのクラスのみを変更してください。

ファイル: BeforeAdvisor.java

package com.w3codebox;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class BeforeAdvisor implements MethodBeforeAdvice{
	@Override
	public void before(Method method, Object[] args, Object target) throws Throwable {
		System.out.println("実際のロジックの前に追加の関心");
		System.out.println("メソッド情報:");+method.getName()+" "+method.getModifiers());
		System.out.println("引数情報:");
		for(Object arg:args)
			System.out.println(arg);
		System.out.println("ターゲットObject:");+target);
		System.out.println("ターゲットオブジェクトクラス名: ");+target.getClass().getName());
	}
}

ファイル: Test.java

package com.w3codebox;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class Test {
public static void main(String[] args) {
	Resource r=new ClassPathResource("applicationContext.xml");
	BeanFactory factory=new XmlBeanFactory(r);
	A a=factory.getBean("proxy",A.class);
        System.out.println("プロキシクラス名: ");+a.getClass().getName());
	a.m();
}
}

出力

プロキシクラス名: com.w3codebox.A$EnhancerByCGLIB$409872b1
実際のロジックの前に追加の心配
メソッド情報:m 1
引数情報:
ターゲットObject:com.w3codebox.A@11dba45
ターゲットオブジェクトクラス名: com.w3codebox.A
実際のビジネスロジック

AfterReturningAdviceの例

実際のビジネスロジックを含むクラスを作成します。

ファイル: A.java

前の例と同じです。

現在、AfterReturningAdviceインターフェースを実装するアドバイザークラスを作成します。

ファイル: AfterAdvisor.java

package com.w3codebox;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class AfterAdvisor implements AfterReturningAdvice{
	@Override
	public void afterReturning(Object returnValue, Method method,
         Object[] args, Object target) throws Throwable {
		System.out.println("アドバイスを返信した後の追加の関心");
	}
}

前の例と同様にxmlファイルを作成しますが、ここでアドバイザープログラムクラスを変更する必要があります。

ファイル: applicationContext.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:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="obj" class="com.w3codebox.A"></bean>
<bean id="ba" class="com.w3codebox.AfterAdvisor"></bean>
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="obj"></property>
<property name="interceptorNames">
<list>
<value>ba</value>
</list>
</property>
</bean>
</beans>

ファイル: Test.java

前の例と同じです。

出力

実際のビジネスロジック
アドバイスを返信した後の追加の関心

3)MethodInterceptor(AroundAdvice)の例

実際のビジネスロジックを含むクラスを作成します。

ファイル: A。java

前の例と同じです。

今、MethodInterceptorインターフェースを実装するアドバイザークラスを作成します。

ファイル: AroundAdvisor.java

package com.w3codebox;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class AroundAdvisor implements MethodInterceptor{
	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		Object obj;
		System.out.println("実際のロジックの前に追加の関心");
		obj=mi.proceed();
		System.out.println("実際のロジックの後の追加の関心");
		return obj;
	}
}

前の例と同様にxmlファイルを作成しますが、ここでアドバイザープログラムクラスを変更する必要があります。

ファイル: applicationContext.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:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="obj" class="com.w3codebox.A"></bean>
<bean id="ba" class="com.w3codebox.AroundAdvisor"></bean>
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="obj"></property>
<property name="interceptorNames">
<list>
<value>ba</value>
</list>
</property>
</bean>
</beans>

ファイル: Test.java

前の例と同じです。

出力

実際のロジックの前に追加の心配
実際のビジネスロジック
実際のロジックの後の追加の心配

4、ThrowsAdviceの例

実際のビジネスロジックを含むクラスを作成します。

ファイル: Validator.java

package com.w3codebox;
public class Validator {
	public void validate(int age)throws Exception{
		if(age<18){
			throw new ArithmeticException("Not Valid Age");
		}
		else{
			System.out.println("vote confirmed");
		}
	}
}

現在、ThrowsAdviceインターフェースを実装するアドバイザークラスを作成します。

ファイル: ThrowsAdvisor.java

package com.w3codebox;
import org.springframework.aop.ThrowsAdvice;
public class ThrowsAdvisor implements ThrowsAdvice{
	public void afterThrowing(Exception ex){
		System.out.println("additional concern if exception occurs");
	}
}

前の例と同様にXMLファイルを作成します。ただし、ValidatorクラスとAdvisorクラスを変更する必要があります。

ファイル: applicationContext.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:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="obj" class="com.w3codebox.Validator"></bean>
<bean id="ba" class="com.w3codebox.ThrowsAdvisor"></bean>
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="obj"></property>
<property name="interceptorNames">
<list>
<value>ba</value>
</list>
</property>
</bean>
</beans>

ファイル: Test.java

package com.w3codebox;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class Test {
public static void main(String[] args) {
	Resource r=new ClassPathResource("applicationContext.xml");
	BeanFactory factory=new XmlBeanFactory(r);
	Validator v=factory.getBean("proxy",Validator.class);
	try{
	v.validate(12);
	}catch(Exception e){e.printStackTrace();}
}
}

出力

java.lang.ArithmeticException: Not Valid Age
additional concern if exception occurs
	at com.w3codebox.Validator.validate(Validator.java:7)
	at com.w3codebox.Validator$FastClassByCGLIB$562915cf.invoke(<generated>)
	at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
	at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invoke
Joinpoint(Cglib2AopProxy.java:692)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.
proceed(ReflectiveMethodInvocation.java:150)
	at org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor.
invoke(ThrowsAdviceInterceptor.java:124)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.
proceed(ReflectiveMethodInvocation.java:172)
	at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.
intercept(Cglib2AopProxy.java:625)
	at com.w3codebox.Validator$EnhancerByCGLIB$4230ed28.validate(<generated>)
	at com.w3codebox.Test.main(Test.java:15)