当需要在街口方法调用后统一处理事务,如关闭资源,可以使用后置通知。Spring中的后置通知(After Returning advice)必须实现 org.springframework.aop.AfterReturningAdvice 接口,如下:
public class MyAfterReturningAdvice implements AfterReturningAdvice {
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object tagert) throws Throwable {
// TODO Auto-generated method stub
System.out.println("close resource");
}
}
当需要在调用接口方法前和调用方法后统一处理事务,可以使用环绕通知。实现环绕通知的MethodInterceptor应当实现下面的接口:
package com.mdd.aop;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MyMethodInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation arg0) throws Throwable {
// TODO Auto-generated method stub
System.out.println("调用方法前执行");
Object obj= arg0.proceed();
System.out.println("调用方法后执行");
return obj ;
}
}
该接口同前两种通知有两个重要区别:1.该通知能够控制目标方法是否真的被调用。通过invocation.proceed()方法来调用。
该通知可以控制返回的对象。可以返回一个与proceed()方法返回对象完全不同的对象。但要谨慎使用。
当目标对象的方法出现异常,会统一在异常通知处理。如果连接点抛出异常,异常通知(throws advice)将在连接点返回后被调用。
package com.mdd.aop;
import java.lang.reflect.Method;
import org.springframework.aop.ThrowsAdvice;
public class MyThrowsAdvice implements ThrowsAdvice {
public void afterThrowing(Method m, Object[] os, Object
target, Exception e)
{
System.out.println("出大事了"+ e.getMessage());
}
}
若只需要目标对象指定的方法织入特定的通知,而不是所有的方法,则需要配置引入通知。通过org.springframework.aop.support.NameMatchMethodPointcutAdvisor来进行配置引入通知。
接口1:Test2ServiceInter.java
package com.mdd.aop;
public interface Test2ServiceInter {
public void sayBye();
}
package com.mdd.aop;
public interface TestServiceInter {
public void sayHello();
}
package com.mdd.aop;
public class Test1Service implements TestServiceInter, Test2ServiceInter{
private String userName;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private int age;
@Override
public void sayHello() {
// TODO Auto-generated method stub
System.out.println("Hello "+userName +"Age " +age);
// int i = 9/0;
// System.out.println(i);
}
@Override
public void sayBye() {
// TODO Auto-generated method stub
System.out.println("ByeBye "+userName +"Age " +age);
}
}
madingding
sayHello
com.mdd.aop.TestServiceInter
com.mdd.aop.Test2ServiceInter
myThrowsAdvice
myMethodAfterAdviceFilter
myMethodInterceptor
执行结果如下,从结果可以看出,通过引入通知过滤之后,只有sayHello方法织入了后置通知,其他方法没有后置通知。
调用方法前执行
Hello madingdingAge 25
调用方法后执行
close resource
*********************
调用方法前执行
ByeBye madingdingAge 25
调用方法后执行