- 浏览: 4399766 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (163)
- 职场 && 心情 (22)
- Java/Basic (17)
- Java/Compression (7)
- Java/Security (20)
- Java/Maven (3)
- Java/Cache (11)
- Eclipse (4)
- Spring (19)
- ORM/Hibernate (2)
- ORM/iBatis (3)
- DB/NoSQL (11)
- DB/MySQL (7)
- DB/MS SQL Server (4)
- OS/Linux (11)
- OS/Mac (7)
- C/C++ (4)
- Server Architecture/Basic (13)
- Server Architecture/Distributed (17)
- Moblie/Andriod (2)
- WebService (3)
- Objective-C (1)
- Html (1)
- 设计模式 (1)
- Scala (0)
- Kafka (1)
最新评论
-
w47_csdn:
证书安装:在"浏览"选项中选择" ...
Java加密技术(九)——初探SSL -
w47_csdn:
spiritfrog 写道你好,我按照你的步骤,tomcat中 ...
Java加密技术(九)——初探SSL -
liuyachao111:
11楼说的对 用@ControllerAdvicepublic ...
Spring 注解学习手札(八)补遗——@ExceptionHandler -
irayslu:
作者你好, 我把你的源码放在jdk6, jdk7 中运行正常, ...
Java加密技术(五)——非对称加密算法的由来DH -
夏季浅忆-卖小子:
为什么不能解压rar格式的压缩包呢
Java压缩技术(三) ZIP解压缩——Java原生实现
自从开始使用Spring,就接触到AOP,但一直未能深入,沉淀一段时间后,开始全面整理!
这里针对一个接口中各个方法做为切面,通过Hello接口实现的例子来诠释Spring AOP 2.0 的特性。
相关内容:
征服Spring AOP—— Schema
征服Spring AOP—— @AspectJ
定义一个接口Hello,定义可触发BeforeAdvice、AfterAdvice、AroundAdvice、ThrowsAdvice、Introduction的方法。
Hello接口
针对Hello接口做具体实现,注意sayHelloThrows方法实现中,刻意抛出异常,用于触发ThrowsAdvice。
SayHello类,对Hello做具体实现。
先来个测试代码:
Spring配置:
这里的org.zlex.aop.Advice用于各个Advice的具体实现,以下是该类中各个方法的诠释。
对上述SayHello类的方法做具体Advice实现:
BeforeAdvice
Spring配置:
控制台输出:
=====Before Advice Begin=====
Before: sayHelloBefore
Say Hello Before!
=====Before Advice End=====
BeforeAdvice在sayHelloBefore方法执行前调用Before类的invoke方法。
AfterAdvice
Spring配置:
控制台输出:
=====After Advice Begin=====
Say Hello After!
After: sayHelloAfter
=====After Advice End=====
BeforeAdvice和AfterAdvice在实现上没有差异,其差别只是触发时机而已。
AfterAdvice只是在目标方法执行后触发,但无法获得目标方法的返回值,对于这点可以通过AfterReturningAdvice增强实现。
AfterReturningAdvice
Spring配置:
控制台输出:
=====After Returning Advice Begin=====
Say Hello After Returning!
After: sayHelloAfterReturning
Return Value: Hello
=====After Returning Advice End=====
AroundAdvice
Spring配置:
控制台输出:
=====Around Advice Begin=====
Around: sayHelloAround
Before
Say Hello Around!
End
=====Around Advice End=====
AroundAdvice是BeforeAdvice和AfterAdvice的综合体。可以,在方法触发前、后分别进行操作。
如果方法执行过程中产生异常,就需要ThrowsAdvice。
AfterThrowingAdvice
Spring配置:
控制台输出:
=====After Throwing Advice Begin=====
Say Hello Throws!
AfterThrowing: sayHelloAfterThrowing
Exception Message: Hello Exception
=====After Throwing Advice End=====
AfterThrowingAdvice是Spring事务处理的核心触发环节。当事务提交产生异常时,将直接触发AfterThrowingAdvice,产生数据库回滚等动作。
除了上述常规增强实现外,还可以通过IntroductionInterceptor构建一个原本不存在的实现。
Introduction
Introduction 可以对一个类的代码在不做任何修改(非入侵式),而使得该类拥有另一套方法,或者说具备另一套本领。
现在,我们就让这个实现了Hello接口的SayHello类拥有Ok接口的实现。
Ok接口,使得Hello接口的所有实现类都绑定这个接口:
IntroductionOk用于实现Ok接口,使得Hello接口实现类都具有sayOk的本领:
Spring配置:
控制台输出:
=====Introduction Advice Begin=====
Introduction: sayHelloIntroduction
Say Hello Introduction!
Ok!
=====Introduction Advice End=====
同样是Hello接口,在执行了sayHelloIntroduction方法时被拦截,同时输出say Hello introduction!,此时还可以执行Ok的方法输出Ok!。显然,Hello的实现类多了Ok接口的本领。
关于表达式符号:
Spring Beans 结构图如下:
代码详见附件!
相关内容:
征服Spring AOP—— Schema
征服Spring AOP—— @AspectJ
这里针对一个接口中各个方法做为切面,通过Hello接口实现的例子来诠释Spring AOP 2.0 的特性。
相关内容:
征服Spring AOP—— Schema
征服Spring AOP—— @AspectJ
定义一个接口Hello,定义可触发BeforeAdvice、AfterAdvice、AroundAdvice、ThrowsAdvice、Introduction的方法。
Hello接口
public interface Hello { /** * 前置增强 */ void sayHelloBefore(); /** * 后置增强 */ void sayHelloAfter(); /** * 后置返回增强 * * @return */ String sayHelloAfterReturning(); /** * 环绕增强 */ void sayHelloAround(); /** * 介入增强 */ void sayHelloIntroduction(); /** * 异常抛出增强 */ void sayHelloThrows(); }
针对Hello接口做具体实现,注意sayHelloThrows方法实现中,刻意抛出异常,用于触发ThrowsAdvice。
SayHello类,对Hello做具体实现。
public class SayHello implements Hello { /* * (non-Javadoc) * * @see org.zlex.aop.Hello#sayHelloBefore() */ public void sayHelloBefore() { System.out.println("Say Hello Before!"); } /* * (non-Javadoc) * * @see org.zlex.aop.Hello#sayHelloAfter() */ public void sayHelloAfter() { System.out.println("Say Hello After!"); } /* * (non-Javadoc) * * @see org.zlex.aop.Hello#sayHelloAfterRunning() */ @Override public String sayHelloAfterReturning() { System.out.println("Say Hello After Returning!"); // 返回值 return "Hello"; } /* * (non-Javadoc) * * @see org.zlex.aop.Hello#sayHelloAround() */ public void sayHelloAround() { System.out.println("Say Hello Around!"); } /* * (non-Javadoc) * * @see org.zlex.aop.Hello#sayHelloAfterThrowing() */ @Override public void sayHelloAfterThrowing() { System.out.println("Say Hello Throws!"); // 强制抛出异常,触发AfterThrowingAdvice throw new RuntimeException("Hello Excetion"); } /* * (non-Javadoc) * * @see org.zlex.aop.Hello#sayHelloIntroduction() */ public void sayHelloIntroduction() { System.out.println("Say Hello Introduction!"); } }
先来个测试代码:
public class AllTest { private ApplicationContext app; private Hello hello; /** * @throws java.lang.Exception */ @Before public void before() throws Exception { app = new ClassPathXmlApplicationContext("applicationContext.xml"); hello = (Hello) app.getBean("hello"); } @Test public void testBefore() { System.out.println("=====Before Advice Begin====="); hello.sayHelloBefore(); System.out.println("=====Before Advice End====="); } @Test public void testAfter() { System.out.println("=====After Advice Begin====="); hello.sayHelloAfter(); System.out.println("=====After Advice End====="); } @Test public void testAfterReturning() { System.out.println("=====After Returning Advice Begin====="); String value = hello.sayHelloAfterReturning(); // AfterReturning获得返回值,但不修改值内容! assertEquals("Hello", value); System.out.println("=====After Returning Advice End====="); } @Test public void testAround() { System.out.println("=====Around Advice Begin====="); hello.sayHelloAround(); System.out.println("=====Around Advice End====="); } @Test public void testAfterThrowing() { System.out.println("=====After Throwing Advice Begin====="); try { hello.sayHelloAfterThrowing(); } catch (Exception e) { assertNotNull(e); } System.out.println("=====After Throwing Advice End====="); } @Test public final void testIntroduction() { System.out.println("=====Introduction Begin====="); // 由于对Hello接口进行了引入,使得实现了Hello接口的类可以具备Ok接口的功能 hello.sayHelloIntroduction(); ((Ok) hello).sayOk(); System.out.println("=====Introduction End====="); } }
Spring配置:
<bean id="hello" class="org.zlex.aop.SayHello" /> <bean id="advice" class="org.zlex.aop.Advice" />
这里的org.zlex.aop.Advice用于各个Advice的具体实现,以下是该类中各个方法的诠释。
对上述SayHello类的方法做具体Advice实现:
BeforeAdvice
/** * Before * * @param joinPoint */ public void before(JoinPoint joinPoint) { System.out.println("Before: " + joinPoint.getSignature().getName()); }
Spring配置:
<!-- before --> <aop:config> <aop:pointcut id="beforePoint" expression="execution(* org.zlex.aop.Hello.sayHelloBefore(..))" /> <aop:aspect id="beforeAspect" ref="advice" > <aop:before method="before" pointcut-ref="beforePoint" /> </aop:aspect> </aop:config>
控制台输出:
引用
=====Before Advice Begin=====
Before: sayHelloBefore
Say Hello Before!
=====Before Advice End=====
BeforeAdvice在sayHelloBefore方法执行前调用Before类的invoke方法。
AfterAdvice
public void after(JoinPoint joinPoint) { System.out.println("After: " + joinPoint.getSignature().getName()); }
Spring配置:
<!-- after --> <aop:config> <aop:pointcut id="afterPoint" expression="execution(* org.zlex.aop.Hello.sayHelloAfter(..))" /> <aop:aspect id="afterAspect" ref="advice" > <aop:after method="after" pointcut-ref="afterPoint" /> </aop:aspect> </aop:config>
控制台输出:
引用
=====After Advice Begin=====
Say Hello After!
After: sayHelloAfter
=====After Advice End=====
BeforeAdvice和AfterAdvice在实现上没有差异,其差别只是触发时机而已。
AfterAdvice只是在目标方法执行后触发,但无法获得目标方法的返回值,对于这点可以通过AfterReturningAdvice增强实现。
AfterReturningAdvice
public void afterReturning(JoinPoint joinPoint, String retVal) { // 返回值参数名称(retVal)必须与XML配置文件中的'returning="retVal"'保持一致 System.out.println("After: " + joinPoint.getSignature().getName()); System.out.println("Return Value: " + retVal); }
Spring配置:
<!-- afterReturning --> <aop:config> <aop:pointcut id="afterReturningPoint" expression="execution(* org.zlex.aop.Hello.sayHelloAfterReturning(..))" /> <aop:aspect id="afterAspect" ref="advice" > <aop:after-returning method="after" pointcut-ref="afterReturningPoint" returning="retVal" /> </aop:aspect> </aop:config>
控制台输出:
引用
=====After Returning Advice Begin=====
Say Hello After Returning!
After: sayHelloAfterReturning
Return Value: Hello
=====After Returning Advice End=====
AroundAdvice
public Object around(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("Around: " + joinPoint.getSignature().getName()); System.out.println("Before"); Object obj = joinPoint.proceed(); System.out.println("End"); return obj; }
Spring配置:
<!-- around --> <aop:config> <aop:pointcut id="aroundPoint" expression="execution(* org.zlex.aop.Hello.sayHelloAround(..))" /> <aop:aspect id="aroundAspect" ref="advice" > <aop:around method="around" pointcut-ref="aroundPoint" /> </aop:aspect> </aop:config>
控制台输出:
引用
=====Around Advice Begin=====
Around: sayHelloAround
Before
Say Hello Around!
End
=====Around Advice End=====
AroundAdvice是BeforeAdvice和AfterAdvice的综合体。可以,在方法触发前、后分别进行操作。
如果方法执行过程中产生异常,就需要ThrowsAdvice。
AfterThrowingAdvice
public void afterThrowing(JoinPoint joinPoint, Exception e) { // 异常参数名称(e)必须与XML配置文件中的'throwing="e"'保持一致 System.out.println("AfterThrowing: " + joinPoint.getSignature().getName()); System.out.println("Exception Message: " + e.getMessage()); }
Spring配置:
<!-- afterThrowing --> <aop:config> <aop:pointcut id="afterThrowingPoint" expression="execution(* org.zlex.aop.Hello.sayHelloAfterThrowing(..))" /> <aop:aspect id="afterThrowingAspect" ref="advice" > <aop:after-throwing method="afterThrowing" pointcut-ref="afterThrowingPoint" throwing="e" /> </aop:aspect> </aop:config>
控制台输出:
引用
=====After Throwing Advice Begin=====
Say Hello Throws!
AfterThrowing: sayHelloAfterThrowing
Exception Message: Hello Exception
=====After Throwing Advice End=====
AfterThrowingAdvice是Spring事务处理的核心触发环节。当事务提交产生异常时,将直接触发AfterThrowingAdvice,产生数据库回滚等动作。
除了上述常规增强实现外,还可以通过IntroductionInterceptor构建一个原本不存在的实现。
Introduction
public Object introduction(ProceedingJoinPoint joinPoint) throws Throwable { System.out .println("Introduction: " + joinPoint.getSignature().getName()); return joinPoint.proceed(); }
Introduction 可以对一个类的代码在不做任何修改(非入侵式),而使得该类拥有另一套方法,或者说具备另一套本领。
现在,我们就让这个实现了Hello接口的SayHello类拥有Ok接口的实现。
Ok接口,使得Hello接口的所有实现类都绑定这个接口:
public interface Ok { void sayOk(); }
IntroductionOk用于实现Ok接口,使得Hello接口实现类都具有sayOk的本领:
public class IntroductionOk implements Ok { @Override public void sayOk() { System.out.println("Ok!"); } }
Spring配置:
<!-- introduction --> <!-- .*+是用于包下的,不是用于接口 +定义目标为该接口的所有实现类 --> <bean id="ok" class="org.zlex.aop.IntroductionOk" /> <aop:config> <aop:aspect ref="advice"> <aop:pointcut id="introductionPoint" expression="execution(* org.zlex.aop.Hello.sayHelloIntroduction(..))" /> <aop:declare-parents implement-interface="org.zlex.aop.Ok" types-matching="org.zlex.aop.Hello+" delegate-ref="ok" /> <aop:around method="introduction" pointcut-ref="introductionPoint" /> </aop:aspect> </aop:config>
控制台输出:
引用
=====Introduction Advice Begin=====
Introduction: sayHelloIntroduction
Say Hello Introduction!
Ok!
=====Introduction Advice End=====
同样是Hello接口,在执行了sayHelloIntroduction方法时被拦截,同时输出say Hello introduction!,此时还可以执行Ok的方法输出Ok!。显然,Hello的实现类多了Ok接口的本领。
关于表达式符号:
引用
.*+定义目标为包下的所有类
+定义目标为该接口的所有实现类
+定义目标为该接口的所有实现类
Spring Beans 结构图如下:
代码详见附件!
相关内容:
征服Spring AOP—— Schema
征服Spring AOP—— @AspectJ
发表评论
-
征服 Redis + Jedis + Spring (三)—— 列表操作
2013-03-06 16:16 84084一开始以为Spring下操 ... -
Memcached笔记——(四)应对高并发攻击
2012-09-13 09:48 29052近半个月过得很痛苦,主要是产品上线后,引来无数机器用户恶意 ... -
征服 Redis + Jedis + Spring (二)—— 哈希表操作(HMGET HMSET)
2012-08-29 18:29 82406不得不说,用哈希操作来存对象,有点自讨苦吃! 不过,既然 ... -
征服 Redis + Jedis + Spring (一)—— 配置&常规操作(GET SET DEL)
2012-08-29 16:30 157624有日子没写博客了,真的是忙得要疯掉。 完成项目基础架构搭建 ... -
Spring 注解学习手札(八)补遗——@ExceptionHandler
2012-08-17 18:35 84289Spring注解,改变了我的 ... -
Spring 注解学习手札(七) 补遗——@ResponseBody,@RequestBody,@PathVariable
2012-08-10 21:27 440157最近需要做些接口服务,服务协议定为JSON,为了整合在Spri ... -
征服 Kestrel + XMemcached + Spring TaskExecutor
2012-07-30 14:43 6262上一篇征服 Kestrel + XMemcached只是对Ke ... -
征服Spring AOP—— @AspectJ
2012-04-10 12:01 18723接N年前写的一篇Spring AOP相关的内容征服Spring ... -
Memcached笔记——(二)XMemcached&Spring集成
2012-04-01 09:55 42408今天研究Memcached的Java的Client,使用XMe ... -
Spring util
2011-02-24 12:02 01,<util:constant/> 取代了之前通 ... -
Spring HttpInvoke实现,以及效率提升!
2010-07-01 17:38 15088最近接手服务器总被人质疑效率问题,说到底是质疑Spring H ... -
Spring 注解学习手札(六) 测试
2010-02-05 16:28 53232既然系统基于注解自成一体,那么基于Spring的测试是否可以依 ... -
Spring 注解学习手札(五) 业务层事务处理
2010-02-04 16:11 25423控制器层、持久层都有 ... -
Spring 注解学习手札(四) 持久层浅析
2010-01-29 11:11 22660今天,我们玩玩数据库,搞搞持久层。不搞太复杂的东西,Sprin ... -
Spring 注解学习手札(三) 表单页面处理
2010-01-26 15:21 40581昨天小歇一天,看着两篇博客迅速飙升的点击率,十分欣慰。今天来研 ... -
Spring 注解学习手札(二) 控制层梳理
2010-01-24 15:53 36641昨天对Spring注解有了一 ... -
Spring 注解学习手札(一) 构建简单Web应用
2010-01-23 13:40 83726近来工作发生了一些变化,有必要学习一下Spring注解了! ... -
关于Spring中Commons Validator的使用说明
2008-09-01 09:57 8194关于Spring中Commons Validator的使用说明 ... -
acegi 我该从哪里取到用户的信息
2006-09-21 17:32 5835项目需要 用acegi做为安全屏障,按acegi 1.0.1 ...
相关推荐
在IT行业中,Spring框架是Java企业级应用开发的首选,而Spring AOP(面向切面编程)则是其核心特性之一,用于实现横切关注...通过学习和实践,你将能更好地掌握这一强大的工具,从而在你的IT职业生涯中征服Spring AOP。
**Spring AOP 基于Schema的AOP支持** 在Spring框架中,AOP(面向切面编程)是一种强大的设计模式,它允许我们定义横切关注点,如日志、事务管理等,这些关注点可以独立于业务逻辑进行管理。Spring AOP提供了基于XML...
Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的重要组成部分,它提供了一种在不修改源代码的情况下,对程序进行功能增强的技术。这个"spring aop jar 包"包含了实现这一功能所需的类和接口,...
Spring AOP 是一种面向切面编程的技术,它允许我们在不修改源代码的情况下,对应用程序的特定部分(如方法调用)进行增强。在 Spring 中,AOP 的实现主要依赖于代理模式,有两种代理方式:JDK 动态代理和 CGLIB 动态...
彻底征服 Spring AOP.
《Spring AOP 源码分析》 在深入探讨Spring AOP之前,我们先要理解AOP(面向切面编程)的基本概念。AOP是一种编程范式,它将关注点分离,使得我们可以将横切关注点(如日志、事务管理、安全检查等)与业务逻辑解耦...
Spring AOP,全称为Aspect Oriented Programming,是面向切面编程的一种编程范式,它是对传统的面向对象编程(OOP)的一种补充。在OOP中,核心是对象,而在AOP中,核心则是切面。切面是关注点的模块化,即程序中的...
本篇文章将深入探讨Spring AOP的Schema实现,即基于XML配置的方式来理解和应用AOP。 一、Spring AOP基础概念 1. 切面(Aspect):切面是关注点的模块化,例如日志、事务管理。在Spring AOP中,切面由通知(Advice...
Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和声明式的方式来处理系统中的交叉关注点问题,如日志、事务管理、安全性等。本示例将简要介绍如何在Spring应用中实现AOP,通过实际的...
现在,我们回到主题——"springaop依赖的jar包"。在Spring 2.5.6版本中,使用Spring AOP通常需要以下核心jar包: - `spring-aop.jar`:这是Spring AOP的核心库,包含了AOP相关的类和接口。 - `spring-beans.jar`:...
**Spring AOP:基于Schema配置的总结与案例** 在Java企业级开发中,Spring框架以其强大的功能和灵活性深受开发者喜爱。其中,Spring AOP(面向切面编程)是解决横切关注点问题的一个重要工具,它允许我们把业务逻辑...
Spring AOP(面向切面编程)是Spring框架的核心特性之一,它允许开发者在不修改源代码的情况下,通过插入切面来增强或改变程序的行为。在本教程中,我们将深入探讨Spring AOP的不同使用方法,包括定义切点、通知类型...
spring-aop-1.1.1.jar spring-aop-1.2.6.jar spring-aop-1.2.9.jar spring-aop-2.0.2.jar spring-aop-2.0.6.jar spring-aop-2.0.7.jar spring-aop-2.0.8.jar spring-aop-2.0.jar spring-aop-2.5.1.jar spring-aop-...
Spring AOP,全称Aspect-Oriented Programming(面向切面编程),是Spring框架的一个重要模块,它通过提供声明式的方式来实现面向切面编程,从而简化了应用程序的开发和维护。在Spring AOP中,我们无需深入到每个...
### Spring AOP面向方面编程原理:AOP概念详解 #### 一、引言 随着软件系统的日益复杂,传统的面向对象编程(OOP)逐渐暴露出难以应对某些横切关注点(cross-cutting concerns)的问题。为了解决这一挑战,面向方面编程...
一、适合人群 1、具备一定Java编程基础,初级开发者 2、对springboot,mybatis,mysql有基本认识 3、对spring aop认识模糊的,不清楚如何实现Java 自定义注解的 ...4、spring boot,mybatis,druid,spring aop的使用
**Spring AOP 实现机制详解** Spring AOP(面向切面编程)是Spring框架的核心特性之一,它允许程序员在不修改源代码的情况下,通过“切面”来插入额外的业务逻辑,如日志、事务管理等。AOP的引入极大地提高了代码的...
基于注解实现SpringAop基于注解实现SpringAop基于注解实现SpringAop
Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和声明式的方式来实现横切关注点,如日志、事务管理、性能监控等。本入门案例将帮助你理解并掌握Spring AOP的基本概念和使用方法。 在...