在上篇文章中学习了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. web.xml常用元素

    web.xml文件是用来初始化配置信息:比如welcome页面.servlet.servlet-mapping.filter.listener.启动加载级别等.当你的web工程没用到这些时,你可以不用 ...

  2. Linux远程备份—ftp方式、NFS方式

    问题:现在项目中每天都有从其它各个系统发过来的数据文件(存放在/var/data目录下,以.txt结尾),虽然很久以前的文件很少用到,占用了很多空间,却不能删除.于是,想把一个月以前的文件都压缩了传到 ...

  3. (转)《深入理解java虚拟机》学习笔记6——类加载机制

    Java虚拟机类加载过程是把Class类文件加载到内存,并对Class文件中的数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的java类型的过程. 在加载阶段,java虚拟机需要完成以下 ...

  4. Mysql 备份恢复之 Mysqldump 工具

    目前正在学习中,看到mysqldump工具导出的数据都是文本形式的,如果是blob或text大对象类型导出的是什么格式的?这个需要后续研究.下面只先总结下简单的. 一.备份1.备份Mysql一个数据库 ...

  5. 十七、mysql 分区之 锁问题

    1.演示一个表锁,基于myisam CMD 1 CMD2 create table e1 (id int ,name char(20)); lock table e1 read; [select|in ...

  6. 创建dblink 同义词

     database link dblink的主要作用是两个数据库间的数据访问 create database link my_test connect to testdbname identified ...

  7. GWT RPC

    GWT RPC GWT RPCRemote Procedure Calls GWT: Google Web Toolkit的缩写,有了 GWT可以使用 Java 编程语言编写 AJAX 前端,然后 G ...

  8. Maven 解决JAR包冲突

    在JAR 冲突的情况下, 利用Eclipse方式解决JAR包冲突时比较方便简洁的,步骤如下 1. 在Eclipse 中打开pom.xml , 选择  “Dependency  Hierarchy” 2 ...

  9. maven插件mybatis-generator生成代码配置

    鸣谢:http://my.oschina.net/u/1763011/blog/324106?fromerr=nJakGh4P (也可参看此博客进行配置) http://www.cnblogs.com ...

  10. uva 125

    floyd 算法   如果存在无数条路  则存在a->a的路  a->b的路径数等于 a->i 和 i->b(0=<i<=_max) 路径数的乘积和 #includ ...