普通通知
/**
* 通知方法的执行顺序;
*
* try{
* @Before
* method.invoke(obj,args);
* @AfterReturning
* }catch(){
* @AfterThrowing
* }finally{
* @After
* }
*
* 正常执行: @Before(前置通知)=====@After(后置通知)====@AfterReturning(正常返回);
* 异常执行: @Before(前置通知)=====@After(后置通知)===@AfterThrowing(方法异常)
*
*/
@Test
public void test03(){
MyMathCalculator bean = ioc.getBean(MyMathCalculator.class);
int add = bean.add(1, 1);
System.out.println("========="+add);
//bean.div(1, 0);
//System.out.println("======");
}
环绕通知
/**
* @throws Throwable
* @Around:环绕:是Spring中强大的通知;
* @Around:环绕:动态代理;
* try{
* //前置通知
* method.invoke(obj,args);
* //返回通知
* }catch(e){
* //异常通知
* }finally{
* //后置通知
* }
*
* 四合一通知就是环绕通知;
* 环绕通知中有一个参数: ProceedingJoinPoint pjp
*
*/
@Around("hahaMyPoint()")
public Object myAround(ProceedingJoinPoint pjp) throws Throwable{
Object[] args = pjp.getArgs();
Object proceed=null;
String name = pjp.getSignature().getName();
try {
//@Before
System.out.println("【环绕前置通知】【"+name+"】【方法开始】");
//就是利用反射调用目标方法即可,就是method.invoke(obj,args)
proceed=pjp.proceed(args);
//@AfterReturing
System.out.println("【环绕返回通知】【"+name+"方法返回,返回值"+proceed+"】");
} catch (Exception e) {
//@AfterThrowing
System.out.println("【环绕异常通知】【"+name+"】方法出现异常,异常信息:"+e);
//为了让外界能知道这个异常,这个异常一定抛出去
throw new RuntimeException(e);
}finally{
//@After
System.out.println("【环绕后置通知】【"+name+"】方法结束");
}
//反射调用后的返回值也一定返回出去
return proceed;
}
多切面的运行顺序
*环绕通知:是
优先于普通通知执行
,执行顺序;
*[
普通前置
]
*{
* try{
*
环绕前置
*
环绕执行:目标方法执行
*
环绕返回
* }catch(){
*
环绕出现异常
* }finally{
*
环绕后置
* }
*}
*[
普通后置
]
*[
普通方法返回
/
方法异常
]
*
新的顺序:
*
(环绕前置
—
普通前置)
—-
目标方法执行
—-
环绕正常返回
/
出现异常
—–
环绕后置
—-
普通后置
—
普通返回或者异常
*
注意:若出现异常,环绕通知必须将异常抛出,普通通知才能出现异常