上一篇演示了,Spring得前通知、后通知、环绕通知,仔细想来前通知、后通知和异常通知,都应该是居于环绕通知开发的,想想如果都能控制目标函数是否能执行,那么要在目标函数执行前后,或者目标函数执行过程中发生异常后进行一些处理,那不是太easy了吗?,按照猜想,前通知、后通知,异常通知 应该是重写invoke方法,在invoke方法里面先执行before在执行proceed就是前通知,先执行proceed在执行afterReturning就是后通知,用在try 里面执行invoke方法就是异常通知。我下面来看spring的源码进行验证
-
-
packageorg.springframework.aop.framework.adapter;
-
importjava.io.Serializable;
-
importorg.aopalliance.intercept.MethodInterceptor;
-
importorg.aopalliance.intercept.MethodInvocation;
-
importorg.springframework.aop.MethodBeforeAdvice;
-
importorg.springframework.util.Assert;
-
-
-
publicclassMethodBeforeAdviceInterceptorimplementsMethodInterceptor,Serializable{
-
privateMethodBeforeAdviceadvice;
-
-
-
publicMethodBeforeAdviceInterceptor(MethodBeforeAdviceadvice){
-
Assert.notNull(advice,"Advicemustnotbenull");
-
this.advice=advice;
- }
-
publicObjectinvoke(MethodInvocationmi)throwsThrowable{
-
this.advice.before(mi.getMethod(),mi.getArguments(),mi.getThis());
-
returnmi.proceed();
- }
- }
-
-
packageorg.springframework.aop.framework.adapter;
-
importjava.io.Serializable;
-
importorg.aopalliance.intercept.MethodInterceptor;
-
importorg.aopalliance.intercept.MethodInvocation;
-
importorg.springframework.aop.AfterAdvice;
-
importorg.springframework.aop.AfterReturningAdvice;
-
importorg.springframework.util.Assert;
-
-
-
publicclassAfterReturningAdviceInterceptorimplementsMethodInterceptor,AfterAdvice,Serializable{
-
privatefinalAfterReturningAdviceadvice;
-
-
-
publicAfterReturningAdviceInterceptor(AfterReturningAdviceadvice){
-
Assert.notNull(advice,"Advicemustnotbenull");
-
this.advice=advice;
- }
-
publicObjectinvoke(MethodInvocationmi)throwsThrowable{
- ObjectretVal=mi.proceed();
-
this.advice.afterReturning(retVal,mi.getMethod(),mi.getArguments(),mi.getThis());
-
returnretVal;
- }
- }
-
-
packageorg.springframework.aop.framework.adapter;
-
importjava.lang.reflect.InvocationTargetException;
-
importjava.lang.reflect.Method;
-
importjava.util.HashMap;
-
importjava.util.Map;
-
importorg.aopalliance.intercept.MethodInterceptor;
-
importorg.aopalliance.intercept.MethodInvocation;
-
importorg.apache.commons.logging.Log;
-
importorg.apache.commons.logging.LogFactory;
-
importorg.springframework.aop.AfterAdvice;
-
importorg.springframework.util.Assert;
-
-
-
publicclassThrowsAdviceInterceptorimplementsMethodInterceptor,AfterAdvice{
-
privatestaticfinalStringAFTER_THROWING="afterThrowing";
-
privatestaticfinalLoglogger=LogFactory.getLog(ThrowsAdviceInterceptor.class);
-
privatefinalObjectthrowsAdvice;
-
-
privatefinalMapexceptionHandlerMap=newHashMap();
-
-
-
publicThrowsAdviceInterceptor(ObjectthrowsAdvice){
-
Assert.notNull(throwsAdvice,"Advicemustnotbenull");
-
this.throwsAdvice=throwsAdvice;
- Method[]methods=throwsAdvice.getClass().getMethods();
-
for(inti=0;i<methods.length;i++){
- Methodmethod=methods[i];
-
if(method.getName().equals(AFTER_THROWING)&
-
-
(method.getParameterTypes().length==1||method.getParameterTypes().length==4)&
-
Throwable.class.isAssignableFrom(method.getParameterTypes()[method.getParameterTypes().length-1])
- ){
-
-
this.exceptionHandlerMap.put(method.getParameterTypes()[method.getParameterTypes().length-1],method);
-
if(logger.isDebugEnabled()){
-
logger.debug("Foundexceptionhandlermethod:"+method);
- }
- }
- }
-
if(this.exceptionHandlerMap.isEmpty()){
-
thrownewIllegalArgumentException(
-
"Atleastonehandlermethodmustbefoundinclass["+throwsAdvice.getClass()+"]");
- }
- }
-
publicintgetHandlerMethodCount(){
-
returnthis.exceptionHandlerMap.size();
- }
-
-
-
privateMethodgetExceptionHandler(Throwableexception){
- ClassexceptionClass=exception.getClass();
-
if(logger.isTraceEnabled()){
-
logger.trace("Tryingtofindhandlerforexceptionoftype["+exceptionClass.getName()+"]");
- }
-
Methodhandler=(Method)this.exceptionHandlerMap.get(exceptionClass);
-
while(handler==null&&!exceptionClass.equals(Throwable.class)){
- exceptionClass=exceptionClass.getSuperclass();
-
handler=(Method)this.exceptionHandlerMap.get(exceptionClass);
- }
-
if(handler!=null&&logger.isDebugEnabled()){
-
logger.debug("Foundhandlerforexceptionoftype["+exceptionClass.getName()+"]:"+handler);
- }
-
returnhandler;
- }
-
publicObjectinvoke(MethodInvocationmi)throwsThrowable{
-
try{
-
returnmi.proceed();
- }
-
catch(Throwableex){
- MethodhandlerMethod=getExceptionHandler(ex);
-
if(handlerMethod!=null){
- invokeHandlerMethod(mi,ex,handlerMethod);
- }
-
throwex;
- }
- }
-
privatevoidinvokeHandlerMethod(MethodInvocationmi,Throwableex,Methodmethod)throwsThrowable{
- Object[]handlerArgs;
-
if(method.getParameterTypes().length==1){
-
handlerArgs=newObject[]{ex};
- }
-
else{
-
handlerArgs=newObject[]{mi.getMethod(),mi.getArguments(),mi.getThis(),ex};
- }
-
try{
-
method.invoke(this.throwsAdvice,handlerArgs);
- }
-
catch(InvocationTargetExceptiontargetEx){
-
throwtargetEx.getTargetException();
- }
- }
- }
通过spring的源码可以确定刚刚的想法。现在明白了前通知和后通知,异常通知是怎么实现的了,但是问题又来了,怎么在我调用业务方法的前去执行invoke方法呢?看来还要继续研究一下^_^
分享到:
相关推荐
**Spring AOP 示例讲解** Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架中的一个重要模块,它提供了一种在不修改源代码的情况下,对程序进行功能增强的技术。这种技术允许开发者将关注点从...
在这个“Spring AOP 1.0示例”中,我们重点关注如何在实际项目中应用这一特性。 首先,我们需要了解AOP的基本概念。AOP的核心思想是将那些影响多个类的公共行为(如日志记录)抽取出来,形成独立的模块,称为切面...
在"基于realproxy的aop使用示例"中,我们可能看到以下步骤: 1. **创建代理类**:首先,我们需要创建一个继承自RealProxy的子类,这个子类负责拦截目标对象的方法调用。在这个子类中,我们可以重写`Invoke`方法,该...
本示例将深入探讨Spring AOP的基础知识,以及如何在实际应用中使用它。 首先,我们来看"LogProfilter.java",这很可能是实现一个日志拦截器的类。在Spring AOP中,这样的类通常被称为切面(Aspect)。切面是封装了...
Spring AOP,全称Aspect-Oriented Programming(面向切面编程),是Spring框架的一个重要组成部分。它提供了一种模块化和声明式的方式来处理系统中的交叉关注点,如日志、性能监控、安全性、事务管理等。通过AOP,...
纯手工打造Emit实现AOP private static void OverrideMethods(TypeBuilder tb, MethodInfo method) { if (!method.IsPublic|| !method.IsVirtual || IsObjectMethod(method)) return; Type[] paramTypes = ...
本示例DEMO "Spring的AOP示例DEMO HELLOWORLD" 将引导我们深入理解Spring AOP的核心概念,并通过一个简单的 HelloWorld 示例来展示其实现过程。 首先,面向切面编程(AOP)是一种编程范式,旨在提高代码的可维护性...
这个“Spring AOP示例”包含了一个具体的实践案例,帮助我们更好地理解和应用Spring AOP。 在Spring AOP中,核心概念有以下几个: 1. **切面(Aspect)**:切面是关注点的模块化,比如事务管理就是一个切面。在...
在这个"Spring AOP简单示例"中,我们将深入探讨这五个关键元素,并通过XML配置来实现它们。 首先,**切面(Aspect)**是关注点的模块化,这些关注点定义了跨越多个对象的行为或责任。在Spring AOP中,切面可以是...
在这个"spring aop API示例"中,我们将深入探讨如何利用Spring AOP的四种通知类型:Before、After、AfterThrowing和Around,以及它们在实际开发中的应用。 1. **Before通知**: 在方法执行前触发,可以用来执行...
本示例将详细阐述如何通过XML配置来实现Spring AOP。 首先,我们需要理解AOP的基本概念。AOP的核心是切面(Aspect),它封装了横切关注点,也就是那些跨越多个对象的业务逻辑。这些关注点通常包括日志、安全检查和...
SpringAOP Spring AOP(面向方面的编程)用于模块化“横截面”服务。 用一种简单的方式,我们可以说它是一个旨在拦截某些进程的组件,例如,在执行某个方法时,Spring AOP可以... 以下示例将向您展示其工作原理
在本示例中,我们将深入探讨Spring框架2.5.6版本中的面向切面编程(AOP)概念。Spring AOP是Spring框架的核心组件之一,它允许开发者在不修改源代码的情况下,对程序进行横切关注点(如日志、事务管理、性能监控等)...
Spring框架的AOP(面向切面编程)正是为了解决这类问题而设计的。AOP允许我们在不修改原有业务逻辑的情况下,将这些共性功能以一种模块化的方式插入到业务代码中,从而提高了代码的可复用性和可维护性。 首先,理解...
在这个"spring aop示例"中,我们看到了如何使用Spring AOP来实现方法执行前打印方法名和参数的功能。这主要涉及到三个方面:AOP的基本概念、注解的使用以及Spring的自动注入。 首先,AOP的核心概念包括切面(Aspect...
Spring IOC AOP学习示例代码,包含Spring常用操作示例和所有所需jar文件。参考博客:http://blog.csdn.net/daijin888888/article/details/51735291
在本教程的示例中,你可能发现了一些配置文件,如`applicationContext.xml`,它们用于装配切面。在Spring XML配置中,我们可以使用`<aop:config>`元素来定义切点表达式,然后使用`<aop:aspect>`元素来声明切面,并将...
以下是一个简单的Spring AOP示例,展示如何使用注解定义切面和通知: ```java // 定义切面 @Aspect @Component public class LoggingAspect { // 定义切入点,匹配所有以'execute'开头的方法 @Pointcut(...
而压缩包子文件的文件名称列表"SSHibernate"可能是表示这是一个关于Spring、Struts和Hibernate整合的示例项目,特别强调了Hibernate的部分。Hibernate是Java领域的一个持久化框架,用于简化数据库操作。在SSH整合...
在IT行业中,面向切面编程(Aspect Oriented Programming,AOP)是一种强大的设计模式,它允许程序员将关注点从核心业务逻辑中分离出来,比如日志记录、事务管理、性能监控等。本例子是一个关于如何在Spring框架中...