`

Spring MethodInterceptor

    博客分类:
  • SSIH
 
阅读更多
我们知道在Spring中一共提供了四种Advice用来支持对方法调用时施加的不同行为.它们包括:
BeforeAdvice:具体接口:MethodBeforeAdvice 在目标方法调用之前调用的Advice
AfterAdvice:具体接口:AfterReturningAdvice 在目标方法调用并返回之后调用的Advice
AroundAdvice:具休接口:MethodInterceptor 在目标方法的整个执行前后有效,并且有能力控制目标方法的执行
ThrowsAdvice:具体接口:ThrowsAdvice 在目标方法抛出异常时调用的Advice
在以上四种Advice中最为特别的就是MethodInterceptor:方法拦截器.它的特别之处在于:首先他所在的包并不Srping中的包而是:org.aopalliance.intercept包.即MethodInterceptor实现了AOP联盟接口,这一点保证了它较之其他的Advice更具有通用性,因为它可以在任何基于AOP联盟接口实现的AOP系统中使用.第二点也就是其最为突出的一点就是它所具有的其他Advice所不能匹敌的功能:在目标方法的整个执行前后有效,并且有能力控制目标方法的执行!
在MethodInterceptor中有一个invoke方法,它们有一个MethodInvocation参数invocation,MethodInterceptor是能通过invocation的proceed方法来执行目标方法的.在显式地调用这个方法时,我们可以在其之前和之后做一些相关操作,实现beforeAdvice和AfterAdvice的功能.


实现MethodInterceptor 接口,在调用目标对象的方法时,就可以实现在调用方法之前、调用方法过程中、调用方法之后对其进行控制。

MethodInterceptor 接口可以实现MethodBeforeAdvice接口、AfterReturningAdvice接口、ThrowsAdvice接口这三个接口能够所能够实现的功能,但是应该谨慎使用MethodInterceptor 接口,很可能因为一时的疏忽忘记最重要的MethodInvocation而造成对目标对象方法调用失效,或者不能达到预期的设想。

关于含有Advice的三种对目标对象的方法的增强,可以参考文章在Spring的IOC容器中装配AOP代理 。

在在Spring的IOC容器中装配AOP代理 的基础上,比较MethodInterceptor 接口的实现与上面提及到的三种接口实现对目标对象方法的增强的功能效果。

我们将从应用中分离出日志切面,,将对日志的操作整合到实现MethodInterceptor 接口的类SpringMethodInterceptor中,该实现类的代码如下所示:

package org.shirdrn.spring.aop;

import java.util.Date;

import org.aopalliance.intercept.MethodInterceptor ;
import org.aopalliance.intercept.MethodInvocation;

public class SpringMethodInterceptor implements MethodInterceptor {

public Object invoke(MethodInvocation invo) throws Throwable {
   Object[] object = invo.getArguments();
   try{
    String date1 = (new Date()).toLocaleString();
    System.out.println("信息:[MethodInterceptor ]["+date1+"]用户 "+object[0]+" 正在尝试登录陆系统...");
  
    Object returnObject = invo.proceed();
  
    String date2 = (new Date()).toLocaleString();
    System.out.println("信息:[MethodInterceptor ]["+date2+"]用户 "+object[0]+" 成功登录系统.");
  
    return returnObject;
   }
   catch(Throwable throwable){
    if(object[0].equals("Jessery")){
     throw new Exception("信息:[MethodInterceptor ]不允许黑名单中用户 "+object[0]+" 登录系统");
    }
   }
   return object;
}

}

程序中,Object returnObject = invo.proceed();很关键,只有通过它来对目标对象方法调用,返回一个Object对象。

调用目标对象方法之前,可以添加跟踪日志,对方法增强,相当于使用MethodBeforeAdvice接口对方法进行增强。

调用目标对象方法之后,也可以添加跟踪日志,对方法增强,相当于使用AfterReturningAdvice接口对方法进行增强。

在执行目标对象方法的过程中,如果发生异常,可以在catch中捕获异常,相当于使用ThrowsAdvice接口对方法进行增强。

上面实现了AOP,同时要在XML中装配,配置如下所示:

<bean id="springMethodInterceptor"
   class="org.shirdrn.spring.aop.SpringMethodInterceptor"
   abstract="false" singleton="true" lazy-init="default"
   autowire="default" dependency-check="default">
</bean>
<bean id="accountService"
   class="org.springframework.aop.framework.ProxyFactoryBean"
   abstract="false" singleton="true" lazy-init="default"
   autowire="default" dependency-check="default">
   <property name="target">
    <ref bean="accountServiceImpl" />
   </property>
   <property name="interceptorNames">
    <list>
     <value>loginMethodBeforeAdvice</value>
     <value>loginAfterReturningAdvice</value>
     <value>loginThrowsAdvice</value>
     <value>springMethodInterceptor</value>
    </list>
   </property>
</bean
对使用MethodInterceptor 对目标对象方法进行增强的配置。

测试主函数同文章在Spring的IOC容器中装配AOP代理 中的相同,如下所示:

package org.shirdrn.main;

import org.shirdrn.interf.AccountServiceInterf;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {

public static void main(String[] args) {
   String name = "shirdrn";
   String pwd = "830119";
   ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
   AccountServiceInterf asi = (AccountServiceInterf)ctx.getBean("accountService");
   asi.login(name, pwd);
}
}

运行输出结果如下所示:

信息:[2008-3-23 17:39:38]用户 shirdrn 正在尝试登录陆系统...
信息:[MethodInterceptor ][2008-3-23 17:39:39]用户 shirdrn 正在尝试登录陆系统...
信息:[MethodInterceptor ][2008-3-23 17:39:42]用户 shirdrn 成功登录系统.
信息:[2008-3-23 17:39:42]用户 shirdrn 成功登录系统.

可见,标示为[MethodInterceptor ]的输出信息,就是MethodInterceptor 对调用目标对象方法的增强的结果。

如果我们使用非法的用户帐户登录系统:

String name = "Jessery";
   String pwd = "jessery";

就会被MethodInterceptor 拦截器拦截,而且抛出异常,如下所示:

信息:[2008-3-23 17:52:18]用户 Jessery 正在尝试登录陆系统...
信息:[MethodInterceptor ][2008-3-23 17:52:18]用户 Jessery 正在尝试登录陆系统...
log4j:WARN No appenders could be found for logger (org.springframework.core.CollectionFactory).
log4j:WARN Please initialize the log4j system properly.
信息:[MethodInterceptor ][2008-3-23 17:52:24]用户 Jessery 登录失败.
Exception in thread "main" java.lang.reflect.UndeclaredThrowableException
at org.shirdrn.impl.AccountServiceImpl$$EnhancerByCGLIB$$32dd7c51.login(<generated>)
at org.shirdrn.main.Main.main(Main.java:16)
用户登录过程中发生异常: Exception
Caused by: java.lang.Exception: 信息:[MethodInterceptor ]不允许黑名单中用户 Jessery 登录系统.
at org.shirdrn.spring.aop.SpringMethodInterceptor.invoke(SpringMethodInterceptor.java:27)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
at org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor.invoke(ThrowsAdviceInterceptor.java:118)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:51)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:53)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:623)
... 2 more

我们可以看到,使用MethodInterceptor 拦截器打印出了三项相关信息:

调用目标对象的方法之前,对其进行了增强:

信息:[MethodInterceptor ][2008-3-23 17:52:18]用户 Jessery 正在尝试登录陆系统...

因为不允许非法用户Jessery登录系统,即不允许Jessery调用login方法,故在调用login方法过程中抛出了异常,并且进行了日志跟踪:

信息:[MethodInterceptor ][2008-3-23 17:52:24]用户 Jessery 登录失败.
Caused by: java.lang.Exception: 信息:[MethodInterceptor ]不允许黑名单中用户 Jessery 登录系统.

总结:

使用Spring的Bean装配AOP,对于MethodBeforeAdvice接口、AfterReturningAdvice接口、ThrowsAdvice接口这三个接口在XML配置文件中配置的顺序对调用目标对象的方法没有关系。

但是如果在使用上述的基础上又使用了MethodInterceptor ,如果MethodInterceptor 配置顺序不同,就可能将对目标对象方法的调用进行拦截,使得我们预期设想的使用AfterReturningAdvice对方法调用之后增强失效。

因此,如果两类Advice同时使用,在装配的时候,在XML配置文件中,将MethodInterceptor 的配置放在其他三种Advice的后面,使得前三种Advice先起作用,最后使用MethodInterceptor 进行拦截。
mark from http://blog.csdn.net/zhangweikai966/article/details/6334366

分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    spring,hibernate整合实现事务管理(MethodInterceptor)

    标题中的“spring,hibernate整合实现事务管理(MethodInterceptor)”是指在Java开发中,使用Spring框架与Hibernate ORM框架进行集成,以实现应用的事务管理。Spring以其强大的依赖注入(DI)和面向切面编程(AOP)...

    org/aopalliance/intercept/MethodInterceptor 类 fro Spring3.0

    nested exception is java.lang.NoClassDefFoundError: org/aopalliance/intercept/MethodInterceptor 就是少了这个包

    Spring使用AOP的三个jar包

    1.0.0.jar`是AOP联盟提供的一个接口库,它定义了一些通用的AOP接口,比如`org.aopalliance.intercept.MethodInterceptor`和`org.aopalliance.intercept.MethodInvocation`,使得不同的AOP框架(如Spring和AspectJ)...

    spring试题(含答案)

    环绕通知的目标对象需要实现的接口是 MethodInterceptor。 7. AOP 将软件系统分为两个部分:切面和业务处理。AOP 是一种设计模式,Spring 提供了一种实现。 8. 在 Spring 中配置 Bean 的 id 属性时,id 属性值不...

    spring-aop-jar

    它包含如`org.aopalliance.intercept.MethodInterceptor`和`org.aopalliance.aop.Advice`等核心接口。 2. spring-aop-4.1.6.RELEASE.jar:这是Spring AOP的特定版本,这里的4.1.6.RELEASE是Spring框架的一个稳定...

    spring aop实现

    本文将深入探讨Spring AOP的实现,包括MethodBeforeAdvice、AfterReturningAdvice以及MethodInterceptor等关键概念。 一、AOP基础知识 AOP的核心思想是横切关注点,即那些与业务逻辑不直接相关的,但需要在多个...

    死磕Spring之AOP篇 - Spring AOP两种代理对象的拦截处理(csdn)————程序.pdf

    在 Spring AOP 中,`ObjenesisCglibAopProxy` 类负责使用 CGLIB 创建代理对象,它会将一系列的 `MethodInterceptor` 注册为 `Callback`,这些 `MethodInterceptor` 执行了 AOP 的逻辑。 在 Spring AOP 的自动代理...

    Spring源码缺失的spring-cglib-repack-3.2.6.jar和spring-objenesis-repack-2.6.jar

    CGlib的核心组件包括Enhancer、Callback和MethodInterceptor等,它们协同工作,使得Spring可以在不修改原有代码的情况下,实现动态代理和增强功能。 **Objenesis** Objenesis是一个轻量级库,用于在Java中创建对象...

    五、Spring源码分析——Spring Aop

    `org.aopalliance.intercept.MethodInterceptor`接口定义了拦截器的行为,而`org.springframework.aop.MethodBeforeAdvice`等类则是具体的通知实现。`org.springframework.aop.aspectj.AspectJExpressionPointcut`类...

    Spring Boot Aspect 切面 AOP 拦截器 Interceptor 监控control请求耗时

    不同于HandlerInterceptor,MethodInterceptor是基于代理的AOP,适用于拦截任何由Spring管理的对象,而不仅仅是控制器。通过实现`org.aopalliance.intercept.MethodInterceptor`接口,并重写`invoke()`方法,我们...

    spring1.2中文版API

    `AOP Alliance`是一组接口,定义了AOP的核心概念,如`MethodInterceptor`和`Pointcut`。`ProxyFactoryBean`用于创建代理对象,它是实现AOP功能的关键,能够拦截目标对象的方法调用,执行相应的切面逻辑。`...

    spring AOP依赖三个jar包

    1. aopalliance-1.0.jar:这是一个非常基础的AOP库,定义了AOP的核心接口,如`org.aopalliance.intercept.MethodInterceptor`和`org.aopalliance.aop.Advice`,这些接口为不同的AOP框架提供了统一的交互方式。Spring...

    简单模拟spring cglib代理

    Spring框架是目前Java企业开发中最为流行的框架之一,它的核心概念之一是面向切面编程(AOP),即在不改变原有代码的基础上,通过代理的方式添加一些横切关注点的代码,如事务管理、日志等。Spring支持两种代理机制...

    第五章:Spring AOP 在 Spring Framework 内部应用1

    Spring AOP在事务管理中扮演了关键角色,通过ProxyTransactionManagementConfiguration和BeanFactoryTransactionAttributeSourceAdvisor等配置,以及TransactionInterceptor实现的MethodInterceptor,实现了基于代理...

    spring和Mybatis整合jar包

    4. **AOP联盟jar包 (6-aop联盟jar包)**:AOP联盟是一组接口,包括了如org.aopalliance.aop.Advice、org.aopalliance.intercept.MethodInterceptor等,它们为不同的AOP框架提供了通用接口,使得Spring的AOP功能可以和...

    Spring之AOP配置文件详解

    这里定义了一个名为`transactionInterceptor`的Bean,该Bean的类型为`com.mooza.spring.aop.TransactionInterceptor`,这通常是一个实现了`MethodInterceptor`接口的类,用于处理事务相关的操作。 ##### 2.4 定义...

    Spring3.2 AOP extra jar

    最后,`aopalliance.jar`是AOP联盟的库,它定义了一些通用的AOP接口,比如`org.aopalliance.intercept.MethodInterceptor`和`org.aopalliance.aop.Advice`,这些接口被多个AOP框架共享,包括Spring和AspectJ。...

    Spring3.1 AOP倚赖jar 包汇总

    最后,`aopalliance-1.0.jar`是AOP Alliance库,它定义了一些通用的AOP接口,如`MethodInterceptor`和`Pointcut`,使得不同的AOP框架(如Spring AOP和AspectJ)可以共享相同的切面代码。这个库是很多AOP实现之间的...

    spring及springmvc源码

    `RequestMappingHandlerAdapter`, `SimpleControllerHandlerAdapter`, `ModelAndView`, `DefaultListableBeanFactory`, `BeanDefinition`, `Advisor`, `Pointcut`, `JoinPoint`, `MethodInterceptor` 等。...

    spring 考试试题

    Spring 框架是Java开发中的一个重要组成部分,它以其轻量级、模块化的设计而闻名。本题涉及了Spring框架的基础知识,包括Spring的核心特性、模块结构、IoC(控制反转)、AOP(面向切面编程)以及Spring与其他框架如...

Global site tag (gtag.js) - Google Analytics