AOP--注解实现通知

AOP关于通知的注解

@Before:前置通知。被拦截方法执行之前执行。

@After:后置通知。被拦截方法执行之后执行,发生异常也会执行,在异常通知之前执行。

@AfterReturning:跑完通知。被拦截方法正常完成之后执行,异常时不执行。

@AfterThrowing:异常通知。被拦截方法发生异常时执行。

@Around:环绕通知。融合了@Before、@AfterReturning、@AfterThrowing,还有类似@After的通知(演化为最终通知)

 

代码实现:

  C1Target 目标类

  C2AdviceAround 环绕通知类

  C3AdviceBefore 四大通知类

  Test注解AOP 测试类(通过注释掉@Component注解 ,实现两种通知测试)

MAVEN环境下配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 开启自动扫描 -->
<context:component-scan base-package="demo03.aspect"/>
<!-- 开启aspectj自动代理 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
package demo03.aspect;

import org.springframework.stereotype.Component;
@Component
public class C1Target {
    public String save(String arg1, int arg2) {
        // System.out.println(10 / 0);
        System.out.println(arg1 + ":" + arg2 + ":保存成功");
        return "【success】";
    }
}
package demo03.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
//@Component
@Aspect
public class C2AdviceAround {
    @Around(value = "bean(c1*)")
    public void doAround(ProceedingJoinPoint pjp) {
        // 【proceeding/proceed:继续做】
        System.out.println("1.前置通知@Before");
        try {
            Object ob = pjp.proceed();
            System.out.println("2.跑完通知@AfterReturning:" + ob);
        } catch (Throwable e) {
            System.out.println("3.异常通知@AfterThrowing:" + e.getMessage());
        }
        System.out.println("4.最终通知(异常了也通知),类似于@After,但是执行时机更靠后。");
    }
}
package demo03.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class C3AdviceBefore {
    @Before(value = "bean(c1*)")
    public void doBefore(JoinPoint jp) {
        System.out.println("---前置通知@Before---");
        // 目标类
        String strClass = jp.getTarget().getClass().getName();
        System.out.println("获取目标对象:" + strClass);
        // 目标函数参数
        Object[] objs = jp.getArgs();
        for (int i = 0; i < objs.length; i++) {
            System.out.println("目标函数参数[" + i + "]:" + objs[i]);
        }
        // 目标函数的方法签名:String ah.demo09aop.p4anno.C1Target.save(String,int)
        System.out.println("获取目标函数的方法签名:" + jp.getSignature());
    }

    @AfterReturning(pointcut = "bean(c1*)", returning = "oRet")
    public void testAfterReturn(JoinPoint jp, Object oRet) {
        System.out.println("---跑完通知@AfterReturning---" + oRet);
    }

    @AfterThrowing(pointcut = "bean(c1*)", throwing = "e")
    public void doThrow(JoinPoint jp, Throwable e) {
        System.out.println(e.getMessage());
        System.out.println("---异常通知@AfterThrowing---");
    }

    @After(value = "bean(c1*)")
    public void doAfter(JoinPoint jp) {
        System.out.println("---后置通知@After---");
    }
}
package demo03.aspect;

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

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

public class Test注解AOP {
@org.junit.Test
public void test环绕通知() {
ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
C1Target target = (C1Target) ac.getBean("c1Target");// 类名首字母小写
target.save("save方法参数名", 998);
((ClassPathXmlApplicationContext) ac).close();
}
}

正常运行结果:

  ---前置通知@Before---
  获取目标对象:demo03.aspect.C1Target
  目标函数参数[0]:save方法参数名
  目标函数参数[1]:998
  获取目标函数的方法签名:String demo03.aspect.C1Target.save(String,int)
  save方法参数名:998:保存成功
  ---后置通知@After---
  ---跑完通知@AfterReturning---【success】

有异常时运行结果:

  ---前置通知@Before---
  获取目标对象:demo03.aspect.C1Target
  目标函数参数[0]:save方法参数名
  目标函数参数[1]:998
  获取目标函数的方法签名:String demo03.aspect.C1Target.save(String,int)
  ---后置通知@After---
  / by zero
  ---异常通知@AfterThrowing---

五大通知实现方式有配置XML实现和利用注解实现,配置XML文件实现过于复杂,建议学会注解实现就可。

猜你喜欢

转载自www.cnblogs.com/jasonjson/p/12398088.html