Spring AOP 学习笔记 - 几种Advice的建立
关键字: spring aopCreating advice:
advice object包含了所有需要添加到aspect的逻辑代码,因为Spring中的joinpoint model是基于method interception的,所以在spring中advice object是可以加载在method调用的范围内的。Spring支持以下集中比较基本的advice类型。
| Advice type | Interface | Descritpion |
| Around | org.aopalliance.intercept.MethodInterceptor | Intercepts calls to the target method |
| Before |
org.springframework.aop.BeforeAdvice org.springframework.aop.MethodBeforeAdvice
|
Called before the target method is invoked |
| After | org.springframework.aop.AfterReturningAdvice | Called after the target method returns |
| Throws | org.springframework.aop.ThrowsAdvice | Called when target method throws an exception |
以上的不同的advice类型保证了开发人员有机会在方法执行的前后和过程,甚至产生异常抛出的时候执行advice中的逻辑代码。下面是一个摘抄至Spring In action相关章节的例子。
首先建立一个接口KwikEMart,Customer可以通过其中的buySquishee方法来购买Squishee。
- public interface KwikEMart {
- Squishee buySquishee(Customer customer) throws KwikEMartException;
- }
同时我们完成一个类ApuEwikEMart来实现它。
- public class ApuKwikEMart implements KwikEMart {
- private boolean squisheeMachineEmpty;
- public Squishee buySquishee(Customer customer)
- throws KwikEMartException {
- if (customer.isBroke()) {
- throw new CustomerIsBrokeException();
- }
- if (squisheeMachineEmpty) {
- throw new NoMoreSquisheesException();
- }
- return new Squishee();
- }
- }
这里定义了一些相关的异常。
首先我们为buySquishee方法加上一个before advice。当Customer购买Squishee时,我们可以给他们一个温暖的问候。扩展org.springframework.aop.MethodBeforeAdvice接口。
- public interface MethodBeforeAdvice {
- void before(Method method, Object[] args, Object target)
- throws Throwable
- }
编写一个欢迎的advice object: WelcomeAdvice来实现MethodBeforeAdvice接口。
- import java.lang.reflect.Method;
- import org.springframework.aop.MethodBeforeAdvice;
- public class WelcomeAdvice implements MethodBeforeAdvice {
- public void before(Method method, Object[] args, Object target) {
- Customer customer = (Customer) args[0];
- System.out.println("Hello " + customer.getName() +
- ". How are you doing?");
- }
- }
method参数表示当前被植入advice的方法,args包含了该方法所有的参数。下面就是把WelcomeAdvice和ApuKwikEMart连接起来。
- <beans>
- <bean id="kwikEMartTarget"
- class="com.springinaction.chapter03.store.ApuKwikEMart"/>
- <bean id="welcomeAdvice"
- class="com.springinaction.chapter03.store.WelcomeAdvice"/>
- <bean id="kwikEMart"
- class="org.springframework.aop.framework.ProxyFactoryBean">
- <property name="proxyInterfaces">
- <value>com.springinaction.chapter03.store.KwikEMartvalue>
- property>
- <property name="interceptorNames">
- <list>
- <value>welcomeAdvicevalue>
- list>
- property>
- <property name="target">
- <ref bean="kwikEMartTarget"/>
- property>
- bean>
- beans>
org.springframework.aop.framework.ProxyFactoryBean是spring框架中很重要的一个类,它可以在不改变被代理类的前提下对其增加一些行为。这里对ApuKwikEMart做了代理,将一系列的interceptors加载在被代理类上,这里就是把welcomeAdvice加载到kwikEMartTarget上。
当用户购买了squishee后,我们需要对用户表示感谢,这里就需要一个after advice来实现它。首先也是扩展org.springframework.aop.AfterReturningAdvice接口。
- public interface AfterReturningAdvice {
- void afterReturning(Object returnValue, Method method,
- Object[] args, Object target) throws Throwable
- }
- }
然后编写ThankYouAdvice来实现它。
- import java.lang.reflect.Method;
- import org.springframework.aop.AfterReturningAdvice;
- public class ThankYouAdvice implements AfterReturningAdvice {
- public void afterReturning(Object returnValue, Method method,
- Object[] arg2, Object target) throws Throwable {
- System.out.println("Thank you. Come again!");
- }
- }
然后就是把ThankYouAdvice和ApuKwikEMart连接起来。其xml文件这里就不重复了。
下面就到了Around Advice的一些简单使用说明,首先扩展org.aopalliance.intercept.MethodInterceptor接口。
- public interface MethodInterceptor extends Interceptor {
- Object invoke(MethodInvocation invocation) throws Throwable;
- }
编写OnePerCustomerInterceptor来实现此接口。
- import java.util.HashSet;
- import java.util.Set;
- import org.aopalliance.intercept.MethodInterceptor;
- import org.aopalliance.intercept.MethodInvocation;
- public class OnePerCustomerInterceptor implements MethodInterceptor {
- private Set customers = new HashSet();
- public Object invoke(MethodInvocation invocation)
- throws Throwable {
- Customer customer = (Customer) invocation.getArguments()[0];
- if (customers.contains(customer)) {
- throw new KwikEMartException("One per customer.");
- }
- Object squishee = invocation.proceed();
- customers.add(customer);
- return squishee;
- }
- }
这里需要注意的是invocation.proceed。执行invocation.proceed时就是对监视方法的执行,在此行前能访问到的信息都是方法执行前的,此后的就是方法执行后的。invocation.proceed方法返回的对象就是被监视方法的返回对象。
当buySquishee方法执行产生异常时,我们同样可以使用Throws Advice来对其进行捕捉。查看org.springframework.aop.ThrowsAdvice接口。
- void afterThrowing(Throwable throwable)
- void afterThrowing(Method method, Object[] args, Object target,
- Throwable throwable)
编写KwikEMartExceptionAdvice来实现以上其中一个方法。
- import org.springframework.aop.ThrowsAdvice;
- public class KwikEMartExceptionAdvice implements ThrowsAdvice {
- public void afterThrowing(NoMoreSquisheesException e) {
- orderMoreSquishees();
- }
- public void afterThrowing(CustomerIsBrokeException e) {
- showCustomerAtmMachine();
- }
- }
这样当buySquishee方法抛出异常时,我们就可以根据异常类型的不同执行相应的方法。
发表评论
- 浏览: 18983 次
- 性别:

- 来自: 成都

- 详细资料
搜索本博客
最新评论
-
Rails实现随机验证码
执行到这一句granite = Magick::ImageList.new('x ...
-- by wzp2000 -
表单验证错误信息一些使用 ...
请问你提到的中文化validator的资料哪里能找到?我一直搜索不到阿..
-- by chaoqun2003 -
Rails实现随机验证码
Thanks a lot
-- by llleelay -
Rails实现随机验证码
我就想拿验证码来防止这个灌水,没想到JAVAEYE的blog也没有这个功能。
-- by sstt -
Rails实现随机验证码
ggggggggggggggggg
-- by sstt






评论排行榜