在上篇文章中学习了Spring AOP,并学习了前置通知和后置通知。地址为:http://www.cnblogs.com/dreamfree/p/4095858.html

在本文中,将继续上篇的学习,继续了解返回通知、异常通知和环绕通知。具体的含义详见代码注释

 package com.yl.spring.aop;

 import java.util.Arrays;

 import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component; @Component
@Aspect
public class LoggingAspect { /**
* 在com.yl.spring.aop.ArithmeticCalculator接口的每一个实现类的每一个方法开始之前执行一段代码
*/
@Before("execution(public int com.yl.spring.aop.ArithmeticCalculator.*(..))")
public void beforeMethod(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
System.out.println("The method " + methodName + " begins with " + Arrays.asList(args));
} /**
* 在com.yl.spring.aop.ArithmeticCalculator接口的每一个实现类的每一个方法执行之后执行一段代码
* 无论该方法是否出现异常
*/
@After("execution(public int com.yl.spring.aop.ArithmeticCalculator.*(..))")
public void afterMethod(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
System.out.println("The method " + methodName + " ends with " + Arrays.asList(args));
} /**
* 方法正常结束后执行的代码
* 返回通知是可以访问到方法的返回值的
*/
@AfterReturning(value="execution(public int com.yl.spring.aop.ArithmeticCalculator.*(..))", returning="result")
public void afterReturning(JoinPoint joinPoint, Object result) {
String methodName = joinPoint.getSignature().getName();
System.out.println("The method " + methodName + " return with " + result);
} /**
* 在方法出现异常时会执行的代码
* 可以访问到异常对象,可以指定在出现特定异常时在执行通知代码
*/
@AfterThrowing(value="execution(public int com.yl.spring.aop.ArithmeticCalculator.*(..))", throwing="ex")
public void afterThrowing(JoinPoint joinPoint, Exception ex) {
String methodName = joinPoint.getSignature().getName();
System.out.println("The method " + methodName + " occurs exception: " + ex);
} /**
* 环绕通知需要携带ProceedingJoinPoint类型的参数
* 环绕通知类似于动态代理的全过程:ProceedingJoinPoint类型的参数可以决定是否执行目标方法。
* 而且环绕通知必须有返回值,返回值即为目标方法的返回值
*/
@Around("execution(public int com.yl.spring.aop.ArithmeticCalculator.*(..))")
public Object aroundMethod(ProceedingJoinPoint pjd) {
Object result = null;
String methodName = pjd.getSignature().getName();
//执行目标方法
try {
//前置通知
System.out.println("The method " + methodName + " begins with " + Arrays.asList(pjd.getArgs()));
result = pjd.proceed();
//返回通知
System.out.println("The method " + methodName + " ends with " + Arrays.asList(pjd.getArgs()));
} catch (Throwable e) {
//异常通知
System.out.println("The method " + methodName + " occurs expection : " + e);
throw new RuntimeException(e);
}
//后置通知
System.out.println("The method " + methodName + " ends");
return result;
} }

切面的优先级  

  为项目增加一个新的切面类,负责验证功能,则需要指定切面执行的顺序。即切面的优先级。具体方法是给切面类增加@Order注解,并指定具体的数字,值越小优先级越高

 package com.yl.spring.aop;

 import java.util.Arrays;

 import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; /**
* 可以使用@Order注解指定切面的优先级,值越小优先级越高
* @author yul
*
*/
@Order(2)
@Component
@Aspect
public class ValidationAspect { @Before("execution(public int com.yl.spring.aop.ArithmeticCalculator.*(..))")
public void vlidateArgs(JoinPoint joinPoint) {
System.out.println("validate: " + Arrays.asList(joinPoint.getArgs()));
}
}

切点表达式的重用:

  在LoggingAspect类中,切点的表达式可以先定义,在使用。

 package com.yl.spring.aop;

 import java.util.Arrays;

 import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Order(1)
@Component
@Aspect
public class LoggingAspect { /**
* 定义一个方法,用于声明切入点表达式。一般的,该方法中再不需要添加其他的代码
* 使用@Pointcut 来声明切入点表达式
* 后面的其他通知直接使用方法名直接引用方法名即可
*/
@Pointcut("execution(public int com.yl.spring.aop.ArithmeticCalculator.*(..))")
public void declareJoinPointExpression() { } /**
* 在com.yl.spring.aop.ArithmeticCalculator接口的每一个实现类的每一个方法开始之前执行一段代码
*/
@Before("declareJoinPointExpression()")
public void beforeMethod(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
System.out.println("The method " + methodName + " begins with " + Arrays.asList(args));
} /**
* 在com.yl.spring.aop.ArithmeticCalculator接口的每一个实现类的每一个方法执行之后执行一段代码
* 无论该方法是否出现异常
*/
@After("declareJoinPointExpression()")
public void afterMethod(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
System.out.println("The method " + methodName + " ends with " + Arrays.asList(args));
} /**
* 方法正常结束后执行的代码
* 返回通知是可以访问到方法的返回值的
*/
@AfterReturning(value="declareJoinPointExpression()", returning="result")
public void afterReturning(JoinPoint joinPoint, Object result) {
String methodName = joinPoint.getSignature().getName();
System.out.println("The method " + methodName + " return with " + result);
} /**
* 在方法出现异常时会执行的代码
* 可以访问到异常对象,可以指定在出现特定异常时在执行通知代码
*/
@AfterThrowing(value="declareJoinPointExpression()", throwing="ex")
public void afterThrowing(JoinPoint joinPoint, Exception ex) {
String methodName = joinPoint.getSignature().getName();
System.out.println("The method " + methodName + " occurs exception: " + ex);
} /**
* 环绕通知需要携带ProceedingJoinPoint类型的参数
* 环绕通知类似于动态代理的全过程:ProceedingJoinPoint类型的参数可以决定是否执行目标方法。
* 而且环绕通知必须有返回值,返回值即为目标方法的返回值
*/
@Around("declareJoinPointExpression()")
public Object aroundMethod(ProceedingJoinPoint pjd) {
Object result = null;
String methodName = pjd.getSignature().getName();
//执行目标方法
try {
//前置通知
System.out.println("The method " + methodName + " begins with " + Arrays.asList(pjd.getArgs()));
result = pjd.proceed();
//返回通知
System.out.println("The method " + methodName + " ends with " + Arrays.asList(pjd.getArgs()));
} catch (Throwable e) {
//异常通知
System.out.println("The method " + methodName + " occurs expection : " + e);
throw new RuntimeException(e);
}
//后置通知
System.out.println("The method " + methodName + " ends");
return result;
} }

当处于不同的类,甚至不同的包时,可以使用包名.类名.方法名

具体代码如下:

 package com.yl.spring.aop;

 import java.util.Arrays;

 import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; /**
* 可以使用@Order注解指定切面的优先级,值越小优先级越高
* @author yul
*
*/
@Order(2)
@Component
@Aspect
public class ValidationAspect { @Before("com.yl.spring.aop.LoggingAspect.declareJoinPointExpression()")
public void vlidateArgs(JoinPoint joinPoint) {
System.out.println("validate: " + Arrays.asList(joinPoint.getArgs()));
}
}

Spring AOP--返回通知,异常通知和环绕通知的更多相关文章

  1. Spring AOP 源码分析 - 筛选合适的通知器

    1.简介 从本篇文章开始,我将会对 Spring AOP 部分的源码进行分析.本文是 Spring AOP 源码分析系列文章的第二篇,本文主要分析 Spring AOP 是如何为目标 bean 筛选出 ...

  2. spring AOP 之一:spring AOP功能介绍

    一.AOP简介 AOP:是一种面向切面的编程范式,是一种编程思想,旨在通过分离横切关注点,提高模块化,可以跨越对象关注点.Aop的典型应用即spring的事务机制,日志记录.利用AOP可以对业务逻辑的 ...

  3. Spring学习十三----------Spring AOP的基本概念

    © 版权声明:本文为博主原创文章,转载请注明出处 什么是AOP -面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术 -主要的功能是:日志记录.性能统计.安全控制.事务处理. ...

  4. Spring -- aop(面向切面编程),前置&后置&环绕&抛异常通知,引入通知,自动代理

    1.概要 aop:面向方面编程.不改变源代码,还为类增加新的功能.(代理) 切面:实现的交叉功能. 通知:切面的实际实现(通知要做什么,怎么做). 连接点:应用程序执行过程期间,可以插入切面的地点. ...

  5. 返回通知&异常通知&环绕通知

    [返回通知] LoggingAspect.java: @Aspect @Component public class LoggingAspect { /* * 在方法正常执行后执行的通知叫返回通知 * ...

  6. spring aop环绕通知

    [Spring实战]—— 9 AOP环绕通知   假如有这么一个场景,需要统计某个方法执行的时间,如何做呢? 典型的会想到在方法执行前记录时间,方法执行后再次记录,得出运行的时间. 如果采用Sprin ...

  7. 【Spring实战】—— 9 AOP环绕通知

    假如有这么一个场景,需要统计某个方法执行的时间,如何做呢? 典型的会想到在方法执行前记录时间,方法执行后再次记录,得出运行的时间. 如果采用Spring的AOP,仅仅使用前置和后置方法是无法做到的,因 ...

  8. Spring AOP使用整理:各种通知类型的介绍

    2.PersonImpl类的源码 public class PersonImpl implements Person { private String name; private int age; p ...

  9. Spring(三)--AOP【面向切面编程】、通知类型及使用、切入点表达式

    1.概念:Aspect Oriented Programming 面向切面编程 在方法的前后添加方法   2.作用:本质上来说是一种简化代码的方式      继承机制      封装方法      动 ...

  10. Spring中关于AOP的实践之Scheme方式实现通知

    (刚开始写东西,不足之处还请批评指正) 关于AOP的通知编写方式有两种,使用Schema-baesd或者使用AspectJ方式,本篇主要介绍Schema-baesd方式的代码实现. (注:代码中没有添 ...

随机推荐

  1. oracle 导入报错 ORA-00959: tablespace 'HB' does not exist

    导入oracle 时发现有几张表导入时一直报错: 报错信息:IMP-00003: ORACLE error 959 encountered   ORA-00959: tablespace 'HB' d ...

  2. easy ui datagrid 数据绑定

    1.前台页面 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> ...

  3. mysql 增加删除用户

    mysql 增加用户 (注意:因为MYSQL环境中的命令,所以后面都带一个分号作为命令结束符) 格式:grant select on 数据库.* to 用户名@登录主机 identified by ' ...

  4. [转载]test后跟je

    今天俺也用OD(OllyDbg)反汇编了个小软件,其中里面有下面两条指令: 没太明白什么意思,google一下,在看雪论坛上发现了一个大虾的解释很详细,记录一下: 1.test a,b 是a与b相与的 ...

  5. [转载]Jquery Form插件表单参数

    表单插件API提供了几个方法,让你轻松管理表单数据和进行表单提交. ajaxForm增 加所有需要的事件监听器,为AJAX提交表单做好准备.ajaxForm不能提交表单.在document的ready ...

  6. hdu 1233

    最小生成树 本来挺简单  一个小错wa了好几遍 /************************************************************************* & ...

  7. sort-based shuffle的核心:org.apache.spark.util.collection.ExternalSorter

    依据Spark 1.4版 在哪里会用到它 ExternalSorter是Spark的sort形式的shuffle实现的关键.SortShuffleWriter使用它,把RDD分区中的数据写入文件. o ...

  8. 如何设置Samza的metrics

    参考这个里边对API的调用 http://samza.incubator.apache.org/learn/documentation/0.7.0/container/metrics.html 参考这 ...

  9. Servlet的一些细节问题

    Servlet的细节问题 1.一个已经注册的Servlet可以被多次映射即: <servlet> <!-- servlet的注册名 --> <servlet-name&g ...

  10. xml格式化

    Vim怎么格式化xml,完全不会,vim的缩进也搞不明白