spring-Aop by aspectj注解 (2) 前置,后置,异常通知

aspectj 通过前置,后置,异常通知注解,表述 spring AOP,测试结构图如下:

aop test结构图为:
这里写图片描述
如果看着不清晰,可参看
http://on-img.com/chart_image/5b0ccc1ae4b0843e3bded605.png

下面是具体的代码测试:
1、 接口定义
package com.msyd.spring.aop.aspectj;
/**表演者(接口)*/
public interface Performer {
    public void perform();
}
2 、目标对象
package com.msyd.spring.aop.aspectj;

/**歌手(目标对象)*/
public class Singer implements Performer {

    public void perform() {
        System.out.println("action:i am a singer!i speak for myself ! ");
    }

}
3 、切面类里定义通知
package com.msyd.spring.aop.aspectj;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

/**观众(切面),可以在歌手表演过程中(目标对象调用过程中,运行时)织入通知。在演员表演之前,做好,关掉手机,演员演的好的时候,观众则鼓掌;演的不好则退票,演出完毕,观众开机@after,回家*/
@Aspect
public class Audience {

    @Pointcut("execution(* com.msyd.spring.aop.aspectj.Performer.perform())")
    public void watch() {

    }

    /**
     * aspectj表达式:切入点表达式
     * 前置通知可以看方法名称,可以获取目标对象和代理对象,但是他们指向的是同一个内存地址,
     * 所以通过打印并不能看出差异,只能通过断点调试才能发现。
     * */
    @Before("watch()")
    public void takeSeat(JoinPoint jp) {
        System.out.println("sitDown as BeforeAdvice,proxy interface.methodName is:" + jp.getSignature().getName());
        System.out.println("proxyObject is :" + jp.getThis() + ",targetObject:" + jp.getTarget());
    }

    /**表演前关机*/

    @Before("watch()")
    public void turnOffPhoneBeforePerform() {
        System.out.println("turnOffPhone()");
    }

    /**后置通知,returning 指定接收返回值得参数名
      * 
      * */
    @AfterReturning(pointcut = "watch()", returning = "ret")
    public void Applaud(JoinPoint jp, Object ret) {
        System.out.println("Applaud and ret=" + ret);
    }

    @AfterThrowing(pointcut = "watch()", throwing = "e")
    public void payOff(JoinPoint jp, Exception e) {
        System.out.println("演出失败 and payOff and e=" + e.getMessage());
    }

    @After(value = "watch()")
    public void goHome(JoinPoint jp) {
        System.out.println("goHome," + jp.toString());
    }
}
4、apectj.xml定义
<?xml version="1.0"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/aop
     http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
        http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
       <!-- 观众(切面)  -->
      <bean class="com.msyd.spring.aop.aspectj.Audience"/>

       <!--歌手(目标对象)  -->
      <bean id="singer" class="com.msyd.spring.aop.aspectj.Singer"/> 

      <!-- aop自动代理 -->
      <aop:aspectj-autoproxy />
</beans>
5 、测试类编写 app.java
package com.msyd.spring.aop.aspectj;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("aspectj.xml", App.class);
        Performer P = (Performer) ac.getBean("singer");//获取目标对象,自动代理可以用接口来接收
        P.perform();
    }
}
6.1、 test调用方法成功结果
sitDown as BeforeAdvice,proxy interface.methodName is:perform
proxyObject is :com.msyd.spring.aop.aspectj.Singer@79ca92b9,targetObject:com.msyd.spring.aop.aspectj.Singer@79ca92b9
turnOffPhone()
action:i am a singer!i speak for myself ! 
Applaud and ret=null
goHome,execution(void com.msyd.spring.aop.aspectj.Performer.perform())
#6.2 、test调用方法失败结果
turnOffPhone()
sitDown as BeforeAdvice,proxy interface.methodName is:perform
proxyObject is :com.msyd.spring.aop.aspectj.Singer@79ca92b9,targetObject:com.msyd.spring.aop.aspectj.Singer@79ca92b9
action:i am a singer!i speak for myself ! 
演出失败 and payOff and e=null
goHome,execution(void com.msyd.spring.aop.aspectj.Performer.perform())

由以上结果可以看出,aspectj的注解:
@After 表示不管成功或者失败,调用方法后都会通知
@AfterThrowing 异常通知
@AfterReturning 后置通知
@Before 前置通知
下一节我们一起学习aspectj的环绕通知。

猜你喜欢

转载自blog.csdn.net/haidaoxianzi/article/details/80489688