上一讲我们使用spring注解的方式理由aop技术实现了方法的拦截,下面我们多使用一点实例,仔细体验下spring2.5 这种技术:
以下所有代码依赖上一讲...
被拦截的业务bean
package cn.com.xinli.service.impl;
import org.apache.log4j.Logger;
import cn.com.xinli.service.PersionSevice;
public class PersionServiceBean implements PersionSevice
{
Logger log=Logger.getLogger(PersionServiceBean.class);
public String getPersonName(Integer personid) {
System.out.println("我是getPersonName()方法");
return "xxx";
}
public void save(String name)
{
System.out.println("我是save()方法");
//throw new RuntimeException("我是异常...");
}
public void update(String name, Integer personid) {
System.out.println("我是update()方法");
}
}
1.得到例外通知
public void save(String name)
{
System.out.println("我是save()方法");
throw new RuntimeException("我是异常...");
}
结果: 注意 在异常发生的时候 后置通知 不会执行
前置通知
进入方法
我是save()方法
最终通知
例外通知:java.lang.RuntimeException: 我是异常...
2. 环绕通知分析:环绕通知的写法固定,入参也必须这么写,并且在方法里面一定要调用 pjp.proceed();
如果这个切面后面还有切面,则先执行后面的切面中的方法, 如果不调用这个方法,后面的切面将不能得到执行,并且
这个自身的切面 中拦截的业务方法也不能执行
//环绕通知,固定写法,可以实现上面的所有通知
@Around("anyMethod()")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
//if(){//判断用户是否在权限
System.out.println("进入方法");
Object result = pjp.proceed();
System.out.println("退出方法");
//}
return result;
}
3.在前置通知中得到方法的 输入参数 ,注解的意思是前置通知执行的条件是 业务方法中只有一个输入参数,并且参数的类型是 String ,我们在 测试用例中 ps.save("huxl") 将得到 前置通知hxl, 执行其他的业务方法,则不会被前置方法拦截到.
@Before("anyMethod() && args(name)")
public void doAccessCheck(String name)
{
System.out.println("前置通知"+name);
}
4.在后置通知中得到业务方法的返回结果 调用 ps.getPersonName(1); 则得到 后置通知:xxx
/*在业务方法执行完毕后,后置通知拿到业务的返回值*/
@AfterReturning(pointcut="anyMethod()",returning="result")
public void doAfterReturning(String result) {
System.out.println("后置通知:"+result);
}
5.在业务方法抛出异常的时候得到在例外通知中得到例外
@AfterThrowing(pointcut="anyMethod()",throwing="e")
public void doAfterThrowing(Exception e) {
System.out.println("例外通知:"+ e);
}