本节主要内容:     1. Spring AOP前置通知案例     2. Spring AOP环绕通知案例     3. Spring AOP异常通知案例     4. Spring AOP注解使用案例

AOP是Aspect Oriented Programming的缩写,意思是面向方面编程,AOP实际是GoF设计模式的延续

关于Spring AOP的一些术语

  • 切面(Aspect):在Spring AOP中,切面可以使用通用类或者在普通类中以@Aspect 注解(@AspectJ风格)来实现
  • 连接点(Joinpoint):在Spring AOP中一个连接点代表一个方法的执行
  • 通知(Advice):在切面的某个特定的连接点(Joinpoint)上执行的动作。通知有各种类型,其中包括"around"、"before”和"after"等通知。许多AOP框架,包括Spring,都是以拦截器做通知模型, 并维护一个以连接点为中心的拦截器链
  • 切入点(Pointcut):定义出一个或一组方法,当执行这些方法时可产生通知,Spring缺省使用AspectJ切入点语法。

通知类型

  • 前置通知(@Before):在某连接点(join point)之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常)
  • 返回后通知(@AfterReturning):在某连接点(join point)正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回
  • 抛出异常后通知(@AfterThrowing):方法抛出异常退出时执行的通知
  • 后通知(@After):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)
  • 环绕通知(@Around):包围一个连接点(join point)的通知,如方法调用。这是最强大的一种通知类型,环绕通知可以在方法调用前后完成自定义的行为,它也会选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常来结束执行

Spring 实现AOP是依赖JDK动态代理和CGLIB代理实现的。 以下是JDK动态代理和CGLIB代理简单介绍     JDK动态代理:其代理对象必须是某个接口的实现,它是通过在运行期间创建一个接口的实现类来完成对目标对象的代理。     CGLIB代理:实现原理类似于JDK动态代理,只是它在运行期间生成的代理对象是针对目标类扩展的子类。CGLIB是高效的代码生成包,底层是依靠ASM(开源的java字节码编辑类库)操作字节码实现的,性能比JDK强。

在Spring中,有接口时将采用JDK的方式实现proxy代理对象,当没有接口时,将采用cglib中的方式实现prixy代理对象。

1 Spring AOP前置通知案例

1.1 问题

使用Spring AOP前置通知,在访问Controller中每个方法前,记录用户的操作日志。

1.2 方案

Spring AOP使用步骤:

1.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建Controller,创建新项目SpringAOP。

导入Spring 环境的jar包 :

如果没有jar包,那么可以上去上面下一个。下载地址:http://yunpan.cn/cdXTcJtZfJqQk  访问密码 6c96

创建员工业务控制器EmpController,并实现员工查询,代码如下:

package com.souvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; @Controller
@RequestMapping("/emp")
public class EmpController {
/**
* 查询员工
*/
@RequestMapping("/findEmp.do")
public String find() {
// 模拟查询员工数据
System.out.println("查询员工数据,发送至列表页面.");
return "emp/emp_list.jsp";
}
}

步骤二:创建方面组件

创建方面组件OperateLogger,并在该类中创建记录用户操作日志的方法,代码如下:

package com.souvc.aspect;

import java.text.SimpleDateFormat;
import java.util.Date;
import org.aspectj.lang.ProceedingJoinPoint;
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; /**
* 用于记录日志的方面组件,演示Spring AOP的各种通知类型。
*/
public class OperateLogger {
/**
* 前置通知、后置通知、最终通知使用的方法
*/
public void log1() {
// 记录日志
System.out.println("-->记录用户操作信息");
}
}

步骤三:声明方面组件

在applicationContext.xml中,声明该方面组件,关键代码如下:

     <!-- 声明方面组件 -->  

    <bean id="operateLogger" class="com.souvc.aspect.OperateLogger"/>

步骤四:将方面组件作用到目标组件上

在applicationContext.xml中,将声明的方面组件作用到com.souvc.controller包下所有类的所有方法上,关键代码如下:

<!-- 声明方面组件 -->
<bean id="operateLogger" class="com.souvc.aspect.OperateLogger"/> <!-- 配置AOP -->
<aop:config>
<aop:aspect ref="operateLogger">
<aop:before method="log1"
pointcut="within(com.souvc.controller..*)"/>
</aop:aspect>
</aop:config>

步骤五:测试

创建Junit测试类TestEmpController,并增加测试查询员工的方法,代码如下:

package com.souvc.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.souvc.controller.EmpController; public class TestEmpController { /**
* 测试查询员工
*/
@Test
public void test1() {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"applicationContext.xml");
EmpController ctl = ctx.getBean(EmpController.class);
ctl.find();
}
}

执行该测试方法,控制台输出效果:

-->记录用户操作信息
查询员工数据,发送至列表页面.

可见,在执行EmpController.find()方法之前,执行了方面组件的记录日志的方法,由于该方法采用AOP面向对象的思想实现的,因此不需要对Controller类做任何改动。

步骤六:扩展

后置通知、最终通知的用法与前置通知完全一致,只需要在配置AOP时将aop:before改为aop: after-returning和aop:after。请自己尝试将前置通知类型改为后置通知、最终通知,并执行测试方法,观察控制台的输出情况。

源码如下:http://yunpan.cn/cdXhDcB4dQMqv  访问密码 0f0b

2 Spring AOP环绕通知案例

2.1 问题

使用Spring AOP环绕通知,在访问Controller中每个方法前,记录用户的操作日志。

2.2 方案

Spring AOP使用步骤:

2.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建方面组件

复用方面组件OperateLogger,在该类中创建新的记录日志的方法log2,代码如下:

package com.souvc.aspect;

import java.text.SimpleDateFormat;
import java.util.Date;
import org.aspectj.lang.ProceedingJoinPoint;
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; /**
* 用于记录日志的方面组件,演示Spring AOP的各种通知类型。
*/
public class OperateLogger {
/**
* 前置通知、后置通知、最终通知使用的方法
*/
public void log1() {
// 记录日志
System.out.println("-->记录用户操作信息");
} /**
* 环绕通知使用的方法
*/
public Object log2(ProceedingJoinPoint p) throws Throwable {
// 目标组件的类名
String className = p.getTarget().getClass().getName();
// 调用的方法名
String method = p.getSignature().getName();
// 当前系统时间
String date = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss")
.format(new Date());
// 拼日志信息
String msg = "-->用户在" + date + ",执行了" + className + "." + method + "()";
// 记录日志
System.out.println(msg); // 执行目标组件的方法
Object obj = p.proceed(); // 在调用目标组件业务方法后也可以做一些业务处理
System.out.println("-->调用目标组件业务方法后..."); return obj;
} }

步骤二:声明方面组件

由于复用的方面组件已经声明,因此该步骤可以省略。

步骤三:将方面组件作用到目标组件上

在applicationContext.xml中,声明方面组件的log2方法,关键代码如下:

<aop:aspect ref="operateLogger">
<aop:around method="log2"
pointcut="within(com.souvc.controller..*)"/>
</aop:aspect>

步骤四:测试

执行测试方法TestEmpController.test1(),控制台输出效果如下图:

-->用户在2015-08-17 05:59:13,执行了com.souvc.controller.EmpController.find()
查询员工数据,发送至列表页面.
-->调用目标组件业务方法后...

项目源码如下: http://yunpan.cn/cdXaI6kmcvVp3  访问密码 f4cd
http://www.cnblogs.com/liuhongfeng/p/4736947.html

Spring 通过来AOP 实现前置,环绕,异常通知,注解(转)的更多相关文章

  1. SpringBoot2.x整合Email并利用AOP做一个项目异常通知功能

    因为不知aop能干嘛,因此用aop做个小功能,再结合最近学的springboot-Email做了个系统异常自动邮件通知的功能, 感觉满满的成就感. AOP不懂的可以看上一篇:https://www.c ...

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

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

  3. [原创]java WEB学习笔记106:Spring学习---AOP的通知 :前置通知,后置通知,返回通知,异常通知,环绕通知

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  4. Spring 通过XML配置文件以及通过注解形式来AOP 来实现前置,环绕,异常通知,返回后通知,后通知

    本节主要内容: 一.Spring 通过XML配置文件形式来AOP 来实现前置,环绕,异常通知     1. Spring AOP  前置通知 XML配置使用案例     2. Spring AOP   ...

  5. [转载] Spring框架——AOP前置、后置、环绕、异常通知

    通知类型: 步骤: 1. 定义接口 2. 编写对象(被代理对象=目标对象) 3. 编写通知(前置通知目标方法调用前调用) 4. 在beans.xml文件配置 4.1 配置 被代理对象=目标对象 4.2 ...

  6. Spring(十八):Spring AOP(二):通知(前置、后置、返回、异常、环绕)

    AspectJ支持5种类型的通知注解: @Before:前置通知,在方法执行之前执行: @After:后置通知,在方法执行之后执行: @AfterRunning:返回通知,在方法返回结果之后执行(因此 ...

  7. Spring初学之annotation实现AOP前置通知、后置通知、返回通知、异常通知。

    实现两个整数的加减乘除.在执行每个方法之前打印日志. ArithmeticCalculator.java: package spring.aop.impl; public interface Arit ...

  8. Spring初学之xml实现AOP前置通知、后置通知、返回通知、异常通知等

    实现两个整数的加减乘除,在每个方法执行前后打印日志. ArithmeticCalculator.java: package spring.aop.impl.xml; public interface ...

  9. Spring AOP--返回通知,异常通知和环绕通知

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

随机推荐

  1. Cocos2d-x3.1 粒子效果演示样例

    这里把粒子的几种效果粘出来,以便以后使用 原文地址:http://blog.csdn.net/qqmcy/article/details/37511259 // // IntervalLayer.cp ...

  2. 《深入浅出 Java Concurrency》—锁紧机构(一)Lock与ReentrantLock

    转会:http://www.blogjava.net/xylz/archive/2010/07/05/325274.html 前面的章节主要谈谈原子操作,至于与原子操作一些相关的问题或者说陷阱就放到最 ...

  3. App域名劫持之DNS高可用 - 开源版HttpDNS方案详解(转)

      http://mp.weixin.qq.com/s?__biz=MzAwMDU1MTE1OQ==&mid=209805123&idx=1&sn=ced8d67c3e2cc3 ...

  4. Android Ant 和 Gradle 打包流程和效率对照

    一.Ant 打包:(下载ant.配置环境变量就不说了) 1.进入命令行模式,并切换到项目文件夹.运行例如以下命令为ADT创建的项目加入ant build支持: android update proje ...

  5. 使用JavaMail发送和接收电子邮件

    一. 为什么要学习JavaMail 为什么要学习JavaMail开发? 如今非常多WEB应用在开发时都须要集成邮件发送功能.比如: 1. 给新注冊的用户自己主动发送一封包括其注冊信息的欢迎E-Mail ...

  6. [TroubleShooting]&#39;trn\bak&#39; is incorrectly formed. SQL Server cannot process this media family.

     SQL Server online consultants came across an interesting scenario where one of our client was una ...

  7. 局域网连接SQL Server数据库配置

    首先要保证两台机器位于同一局域网内,然后打开配置工具→SQL Server配置管理器进行配置.将MSSQLSERVER的协议的TCP/IP的(IP1.IP2)TCPport改为1433,已启用改为是. ...

  8. The app references non-public selectors in payload With Xcode6.1

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢! 原文地址: p=591" style="color: rgb(255, 97, 0 ...

  9. #Windows Phone:在HTML5专案中,如何从Javascript传送字串到C#的APP端

    原文:#Windows Phone:在HTML5专案中,如何从Javascript传送字串到C#的APP端 #Windows Phone:在HTML5专案中,如何从Javascript传送字串到C#的 ...

  10. ajax j跨域请求sonp

    需求 遇到的问题 解决方案 需求 如今,该项目需要获得数据访问外部链接.它是跨域.使用ajax 直提示: 遇到的问题 1. 怎样使用ajax 跨域请求数据 2. 能不能post请求 解决的方法 经过网 ...