那些年我们一起着迷的Spring:AOP-Advice应用(十)

转自:Spring入门(Schema-based AOP其三)

<bean id="moocAspect" class="com.imooc.aop.schema.advice.MoocAspect"></bean>
<bean id="aspectBiz" class="com.imooc.aop.schema.advice.biz.AspectBiz"></bean>

<aop:config>
    <aop:aspect id="moocAspectAOP" ref="moocAspect">
        <aop:pointcut id="moocPiontcut" 
            expression="execution(* com.imooc.aop.schema.advice.biz.*Biz.*(..))"/>
        <!--前置通知-->
        <aop:before method="before" pointcut-ref="moocPiontcut"/>
		  <!--正常返回后通知,可限制返回值returning="retVal,异常则不会返回-->
		<aop:after-returning method="afterReturning" pointcut-ref="moocPiontcut"/>
		  <!--After throwing advice,在抛出异常之后返回;正常情况下不返回--> 
		<aop:after-throwing method="afterThrowing" pointcut-ref="moocPointcut"/>
		 <!--After(finally) advice,无论是否异常都会执行finally--> 
		<aop:after method="after" pointcut-ref="moocPointcut"/>
		<!--Around advice 环绕通知 这个通知的方法的第一个参数必须是ProceedingJoinPoint类型-->
		<aop:around method="around" pointcut-ref="moocPiontcut"/>
    </aop:aspect>
</aop:config>

//MoocAspect被我们声明成了切面类。 
public class MoocAspect{
    
    

    public void before(){
    
    
        System.out.println("MoocAspect Before.");
    }    
	 public void afterReturning(){
    
    
        System.out.println("MoocAspect afterReturning.");
    }
	public void afterThrowing(){
    
    
   	 System.out.println("MoocAspect afterThrowing.");
	}
	public void after(){
    
    
	    System.out.println("MoocAspect after.");
	}
	/*必须有一个参数,第一个参数必须是ProceedingJoinPoint 这种类型,这个类型的参数有一个proceed方法,也就是执行当前业务的方法。
	在具体业务执行之前或者之后都可以进行我们想做的事情。
	这里考虑这个异常是否要捕捉到并处理,如果不需要可以写为
	public Object around(ProceedingJoinPoint pjp) throw Throwable{…}
	*/
	public Object around(ProceedingJoinPoint pjp){
    
    
	    Object obj=null;
	    try{
    
    
	        System.out.println("MoocAspect around 1.");
	        obj=pjp.proceed();//执行当前业务的方法
	        System.out.println("MoocAspect around 2.");
	    }catch(Throwable e){
    
    
	        e.printStackTrace();
	    }
	    return obj;
	}
}
//业务类
public class AspectBiz {
    
    

    public void biz() {
    
    
        System.out.println("AspectBiz biz.");
        // throw new RuntimeException();
    }
}

单元测试

@Test
public void testBiz() {
    
    
    AspectBiz biz = super.getBean("aspectBiz");
    biz.biz();
}
执行单元测试方法,输出 
MoocAspect before. 
MoocAspect around 1. 
AspectBiz biz. 
MoocAspect around 2. 
MoocAspect afterReturning. 
MoocAspect after.

即使是抛出异常了,也会执行after这个方法,输出为 
MoocAspect before. 
MoocAspect around 1. 
AspectBiz biz. 
MoocAspect around 2. 
MoocAspect afterThrowing. 
MoocAspect after.

aop:pointcut中的expression就是一个切入点的表达式,execution执行方法在* com.imooc.aop.schema.advice.biz这个包下所有以Biz结尾的类的所有方法,这里是AspectBiz类里边有个biz方法。这个切入点切到了这个表达上,它的id是moocPointcut。
aop:before中的before方法什么时候会被触发?就是当对应包下边所有以Biz结尾的类的方法在执行之前都会执行这个方法,也就是MoocAspect的before方法。因为这个pointcut-ref引用的就是这样的一个pointcut。

Advice parameters

public class AspectBiz {
    
    

    public void biz() {
    
    
        System.out.println("AspectBiz biz.");
//      throw new RuntimeException();
    }

    public void init(String bizName, int times) {
    
    
        System.out.println("AspectBiz init : " + bizName + "   " + times);
    }
}

回到配置文件里 仍然使用around,pointcut写得具体一些,AspectBiz里的init方法,参数分别是String,int,后边要加上参数名称。

<aop:around method="aroundInit" 
        pointcut="execution(* com.imooc.aop.schema.advice.biz.AspectBiz.init(String, int)) and args(bizName, times)"/>

实现类的aroundInit方法,和之前around方法不同的是,要加上两个参数

public Object aroundInit(ProceedingJoinPoint pjp, String bizName, int times) {
    
    
    System.out.println(bizName + "   " + times);
    Object obj = null;
    try {
    
    
        System.out.println("MoocAspect aroundInit 1.");
        obj = pjp.proceed();
        System.out.println("MoocAspect aroundInit 2.");
    } catch (Throwable e) {
    
    
        e.printStackTrace();
    }
    return obj;
}

单元测试

@Test
public void testInit() {
    
    
    AspectBiz biz = super.getBean("aspectBiz");
    biz.init("moocService", 3);
}

在这里插入图片描述
带参数的环绕通aroundInit知包含在不带参数的around中

猜你喜欢

转载自blog.csdn.net/eluanshi12/article/details/96995532