在《初识Spring》中我们了解到Spring支持AOP且可配置方法的前置曾强和后置曾强,但其实Spring支持多种曾强类型。下面同过一些例子来介绍Spring的几种常用的曾强(前置增强和后置曾强不再进行介绍,详情可参阅《初识Spring》这篇博客)。

异常抛出曾强

异常抛出曾强的特点是在目标方法抛出异常时织入曾强处理。首先我们要编写一个实现异常曾强代码的类,给类实现ThrowsAdvice接口。如下所示:

package cn.wz.aop;

import java.lang.reflect.Method;

import org.apache.log4j.Logger;
import org.springframework.aop.ThrowsAdvice;
public class ErrorLogger implements ThrowsAdvice {
Logger log=Logger.getLogger(ErrorLogger.class);
/**
* 实现异常曾强代码的方法
* @param method 目标方法名
* @param args 向目标方法传入的参数
* @param target 目标方法所在的类的实例
* @param e 目标方法内所抛出的异常对象
*/
public void afterThrowing(Method method,Object[] args,Object target,Exception e) {
log.error(method.getName()+"发生异常:"+e);
}
}

 

上述代码通过实现ThrowsAdvice接口实现异常抛出曾强,其中ThrowsAdvice接口中没有定义任何方法,但我们在定义异常抛出的曾强方法时必须遵守以下方法签名:

void afterThrowing([Method method,Object [] arguments,Object target,]Throwable ex)

这里Spring规定了方法名必须是“afterThrowing”。方法参数只有最后一个是必须的,前面三个参数是可选的,但是前面三个参数只能是要么都提供,要么都不提供!否则则无法实现曾强。下面编写测试类进行测试:

package cn.wz.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class ExceptionTest {
public static void main(String[] args) throws Exception {
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
ExceptionTest bean = context.getBean("test",ExceptionTest.class);
bean.add();
} public void add() throws Exception {
throw new Exception("错误"); }
}

最终运行结果:

对于Spring配置文件的配置方法与前置增强和后置曾强的配置方法相同这里不再进行演示,

环绕曾强

环绕曾强在目标方法的前后都可以织入曾强处理。环绕增强是功能最强大的增强处理,Spring把目标方法的控制权全部交给了它。在环绕曾强处理中,可以获取或修改目标方法的参数,返回值,可以对它进行异常处理,甚至可以决定目标方法是否执行!

好了下面来看看如何实现环绕曾强吧。首先还是要定义实现环绕曾强代码的类,该类实现了MethodInterceptor接口的invoke()方法,在invoke()方法中编写曾强代码。

package cn.wz.aop;

import java.lang.reflect.Method;
import java.util.Arrays; import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.log4j.Logger;
public class ErrorLogger implements MethodInterceptor {
Logger log=Logger.getLogger(ErrorLogger.class); public Object invoke(MethodInvocation arg0) throws Throwable {
Method method = arg0.getMethod();
Object[] arguments = arg0.getArguments();
Object target = arg0.getThis();
log.info("调用"+target+"的"+method.getName()+"方法。方法入参:"+Arrays.toString(arguments)); try {
Object result = arg0.proceed();
log.info("调用"+target+"的"+method.getName()+"方法。方法返回值:"+result);
return result;
} catch (Exception e) {
log.error(method.getName()+"方法异常:"+e);
}
return null;
}
}

上述代码通过MethodInterceptor接口实现了环绕增强。该接口要求实现invoke方法,其参数MethodInvocation不但疯转了目标方法及其入参数组,还封装了被代理的目标对象。通过proceed方法可以调用目标对象响应的方法,从而实现对目标方法的完全控制。借助异常抛出曾强的测试代码进行测试其运行结果如下:

使用注解实现曾强

除了实现Spring提供的特定接口外,Spring还可以通过集成AspectJ实现了以注解的方式定义增强类。大大减少了配置文件中的工作量。

注意:使用Aspectj是要确保JDK的版本是5.0或以上的版本,否则将无法使用注解技术,其次还要引入asm模块的jar包到项目中

前置曾强和后置曾强类:

package cn.wz.aop;

import org.apache.log4j.Logger;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before; @Aspect
public class UserLogger {
private static final Logger log=Logger.getLogger(UserLogger.class);
@Before("execution(public void add())")
public void before(){
log.info("前置增强");
}
@AfterReturning("execution(public void add())")
public void afterReturning(){
log.info("后置增强");
}
}

在Spring配置文件中的配置如下:

异常抛出增强类:

package cn.wz.aop;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect; @Aspect
public class Error_Logger {
private static final Logger log=Logger.getLogger(UserLogger.class);
@AfterThrowing(pointcut="execution(public void add())" ,throwing="e")
public void agterThrowing(JoinPoint jp,Exception e){
log.error(jp.getSignature().getName()+"发生异常:"+e);
}
}

环绕增强类:

package cn.wz.aop;

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class ArounsLogger {
private static final Logger log=Logger.getLogger(UserLogger.class);
@Around("execution(public void add())")
public Object aroundLogger(ProceedingJoinPoint jp) throws Throwable{
System.out.println("前置增强");
Object obj = jp.proceed();//调用原始方法
System.out.println("后置增强");
return obj; }
}

SpringAOP使用扩展的更多相关文章

  1. 面向切面编程AOP

    本文的主要内容(AOP): 1.AOP面向切面编程的相关概念(思想.原理.相关术语) 2.AOP编程底层实现机制(动态代理机制:JDK代理.Cglib代理) 3.Spring的传统AOP编程的案例(计 ...

  2. Spring第二天

    Spring第二天 整体课程安排(3天+2天): 第一天:Spring框架入门.IoC控制反转的配置管理.Spring Web集成.Spring Junit集成. 第二天:Spring AOP面向切面 ...

  3. ssm单项目整合

    目录 前言 创建maven项目 添加依赖 配置文件 总览 jdbc配置 mybatis配置 dao层配置 service层配置 事务配置 controller配置 web.xml 使用 前言 spri ...

  4. SpringAOP详解(转载大神的)

    AOP(Aspect-Oriented Programming)这个东西,名字与 OOP 仅差一个字母,其实它是对 OOP 编程方式的一种补充,并非是取而代之.翻译过来就是"面向方面编程&q ...

  5. Spring-AOP实践 - 统计访问时间--StopWatch

    公司的项目有的页面超级慢,20s以上,不知道用户会不会疯掉,于是老大说这个页面要性能优化.于是,首先就要搞清楚究竟是哪一步耗时太多. 我采用spring aop来统计各个阶段的用时,其中计时器工具为S ...

  6. Spring-AOP用法总结

    前言     Spring AOP的实现方法很多,在项目开发中具体采用什么方式,需要按实际情况来选择,每一种的用法,有其一定的实用价值,所以本文将各种使用方法进行了具体实现.主要包括Advice的be ...

  7. SpringAop详解

    近几天学习了一下SpringAop在网上找了一些资料,此链接为原文链接http://www.cnblogs.com/xrq730/p/4919025.html AOP AOP(Aspect Orien ...

  8. 扩展Spring切面功能

    概述 Spring的切面(Spring动态代理)在Spring中应用十分广泛,例如还有事务管理,重试等等.网上介绍SpringAop源码很多,这里假设你对SpringAop有基本的了解.如果你认为Sp ...

  9. springaop——AspectJ不可不知的细节

    springaop简介 springaop是spring对AOP技术的具体实现,它是spring框架的核心技术.springaop底层使用JDK动态代理或CGLIB动态代理技术实现. 应用场景: 在多 ...

随机推荐

  1. WebRTC实现网页版多人视频聊天室

    因为产品中要加入网页中网络会议的功能,这几天都在倒腾 WebRTC,现在分享下工作成果. 话说 WebRTC Real Time Communication 简称 RTC,是谷歌若干年前收购的一项技术 ...

  2. python Scrapy

    由于项目要使用新闻,大量的数据所以想到了python的scrapy 下面大致讲一讲如何安装使用,直到整个新闻采集模块完成,网址什么的自己找 这里只是示范这里的项目环境是python 2.66 cent ...

  3. 基于ABP的应用执行Update-Database出现异常的解决办法

    今天在QQ群中看到有网友在更新数据库执行Update-Database时出现下面的错误: 为了能让搜索引擎搜索到,特意加上该错误的文字说明: 在与 SQL Server 建立连接时出现与网络相关的或特 ...

  4. 可在广域网部署运行的QQ高仿版 -- GG叽叽V3.7,优化视频聊天、控制更多相关细节

    在广域网中,由于网络的结构纷繁复杂.而且其实时状况又是千变万化的,所以,要使广域网中的视频聊天达到一个令人满意的效果,存在诸多挑战.这次发布的GG 3.7版本尝试在这一方向上做一些努力,据我自己测试, ...

  5. 压力测试工具ab使用

    ab全名是apache bench,是apache自带的一款压力测试工具.它通过创建多个线程来模拟并发,测试目标是基于URL的,因此不论是什么web服务器都可以支持. 使用ab非常简单,进入apach ...

  6. 相识Highcharts,几分钟玩转Highcharts

    Highcharts是一个功能强大.开源.美观.图表丰富.兼容绝大多数浏览器的纯js图表库. 官网:http://www.hcharts.cn/ 我觉得对于刚接触一个东西的新手来说,有时候对一个东西真 ...

  7. JavaScript思维导图—运算符

    JavaScript思维导图-来自@王子墨http://julying.com/blog/the-features-of-javascript-language-summary-maps/

  8. 据说每个大牛、小牛都应该有自己的库——DOM处理续

    在上篇据说每个大牛.小牛都应该有自己的库——DOM处理最后剩下attr()和css()方法没有处理,因为这两个方法当时并不自计划中,是写着写着突然想到的,一时间没有特别好的思路,当时已十一点多了,就去 ...

  9. Behind RabbitMQ Exchange Types

    what's the underlying philosophy behind "exchange types"? In a word, it is all about imple ...

  10. Hibernate缓存(转)

    来自:http://www.cnblogs.com/wean/archive/2012/05/16/2502724.html 一.why(为什么要用Hibernate缓存?) Hibernate是一个 ...