`
billy_zh
  • 浏览: 62157 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

jboss seam 中的Interceptor

阅读更多
在Seam Framework中,Interceptor完成简单的AOP功能,本文分析Interceptor的处理流程。

在创建Seam组件的Component类时,有一段初始化Interceptor的代码:
if ( interceptionEnabled )  {
   initInterceptors();
}

不过可以通过在Seam组件上使用@BypassInterceptors注解以禁止使用Interceptor.

Component.initInterceptors()
  initDefaultInterceptors();  // 初始化默认的Interceptor

  // 加入用户的Interceptor.
  for (Annotation ann : getBeanClass().getAnnotations() ) {
    if (annotation.annotationType().isAnnotationPresent(Interceptors.class)) {
      Class[] classes = annotation.annotationType().getAnnotation(Interceptors.class).value;
      addInterceptor(new Interceptor(classes, annotation, this));
    }
  }  

  这里的Interceptors注解类可以是org.jboss.seam.annotations.intercept.Interceptors
  也可以是 javax.interceptor.Interceptors,
  要注意的是,Interceptors注解不能直接加到Bean中,而应该通过一个注解间接地加到Bean上,
  通过上面的代码可以看出这一点。

Component.initDefaultInterceptors()
  //根据组件类型初始化Interceptors,这里只给出其中的两个:
  if (getType()!=ENTITY_BEAN) {
    addInterceptor(new Interceptor(new MethodContextInterceptor(), this));
  }  
  if (needsInjection() || needsOutjection()) { // 需要注入或反向注入
    addInterceptor(new Interceptor(new BijectionInterceptor(), this));    
  }

  BijectionInterceptor即双向注入拦截器,稍后我们来看它是如何工作的。

在Seam Framework中,并不要求Interceptor继承自某个Interface或Class,
只要在Invoke方法上加@AroundInvoke注解即可,这样任何一个Pojo类都可以成为Interceptor,
当然,如果让Interceptor继承自Seam中的AbstractInterceptor,那么能得到一些性能上的优化,
稍后我们会看到这一点。

下面以普通JavaBean为例来说明Interceptor的处理流程

Component.initantiateJavaBean()
  Object bean = getBeanClass().newInstance();
  JavaBeanInterceptor interceptor = new JavaBeanInterceptor(bean, this);
  bean = wrap(bean, interceptor);
  interceptor.postConstruct();
  return bean;


在bean创建后,为其创建一个JavaBeanInterceptor,然后创建一个proxy对象返回,
这样对bean的所有调用都将由JavaBeanInterceptor进行处理。

JavaBeanInterceptor.invoke(proxy, method, proceed, params)
  Object result = interceptInvocation(method, params);
  return result==bean ? proxy : result;


JavaBeanInterceptor.interceptInvocation(method, params)
  return invoke(new RootInvocationContext(bean, method, params), EventType.AROUND_INVOKE);


RootInterceptor.invoke(invocation, invocationType)
  
  if (!isSeamComponent || !Lifecycle.isApplicationInitialized()) {
    // 不是一个seam组件,直接调用方法
    return invocation.proceed(); 
  }
  else {
    return createInvocationContext(invocation, invocationType).proceed();
  }


RootInterceptor.createInvocationContext(invocation, invocationType)
  if (isProcessInterceptors(invocation.getMethod(), invocation.getTarget())) {
    // 检查method是否要处理拦截,在Method上也可以加BypassInterceptors注解来忽略拦截器
    return createSeamInvocationContext(invocation, invocationType);
  }
  else {
    return invocation;
  }


SeamInvocationContext.proceed()
  if (location == interceptors.size) {
    // 所有Interceptor是否已处理完
    return context.proceed();
  }
  else {
    Object userInterceptor = userInterceptors.get(location);
    Interceptor interceptor = interceptors.get(location);
    location++;
    switch (eventType) {
      case AROUND_INVOKE:
        if (interceptor.isOptimized()) { 
          // 检查Interceptor是否继承自OptimizedInterceptor
          return ((OptimizedInterceptor)userInterceptor).aroundInvoke(this);
        }
        else {
          return interceptor.aroundInvoke(this, userInterceptor);
        }
      case .....
    }
  }

  这是一个Interceptor链的处理方法,每进入一个Interceptor,location加一,
  直到所有Interceptor都进入才执行实际的业务方法,然后按相反顺序退出Interceptor链,
  所以在业务方法中必须调用invocation.proceed()以使Interceptor链进行下去。

Interceptor.aroundInvoke(invocation, userInterceptor)
  return aroundInvokeMethod==null ?
        invocation.proceed() :
        Reflections.invoke( aroundInvokeMethod, userInterceptor, invocation );

  如果aroundInvokeMethod为null,则继续下一Interceptor,
  否则执行userInterceptor的aroundInvokeMethod。


双向注入

双向注入由BijectionInterceptor拦截器完成,双向注入只是IoC的一个扩展,其中
正向注入把Context中的对象到Seam组件中,反向注入把Seam组件的对象注入到Context中,

BijectionInterceptor.aroundInvoke(invocation)
  Component component = getComponent();
  boolean enforceRequired = !component.isLifecycleMethod(invocation.getMethod());
  // 正向注入
  component.inject(invocation.getTarget(), enforceRequired);
  // 业务方法
  Object result = invocation.proceed();
  // 反向注入
  component.outject(invocation.getTarget(), enforeRequried);
  component.disinject(invocation.getTarget());
  return result;

有关双向注入的详细内容请查看后续文章。
分享到:
评论

相关推荐

    jboss seam 中文文档集合

    **JBoss Seam 中文文档集合概述** JBoss Seam 是一个开源的应用框架,它结合了JavaServer Faces (JSF)、Java Persistence API (JPA)、Enterprise JavaBeans (EJB) 3.0 和其他Java EE组件,旨在简化企业级开发。这个...

    jboss seam 2.0 中文手册

    整理自jboss seam 中文站,压缩为chm格式,便于广大jboss seam爱好者阅读,所有版权归jboss seam中文站所有。

    Jboss seam3 实战

    标题中的“Jboss seam3 实战”表明,本文将重点介绍JBoss Seam框架的第三个版本的实际应用。JBoss Seam是一个开源的Java EE框架,它通过依赖注入和会话模型,简化了基于Java EE的企业级应用开发。Seam框架为开发者...

    JBOSS SEAM组件中文手册

    **JBoss Seam组件中文手册** **一、Seam框架概述** Seam是一个开源的企业级Java框架,由JBoss公司开发,旨在简化Java EE应用程序的开发。它将多种技术如JavaServer Faces (JSF),Java Persistence API (JPA),EJB 3...

    JBoss Seam入门介绍

    在Seam中,一切皆组件,无论你是倾向于采用分层架构(如J2EE)还是简单的架构,都可以得到支持。组件可以是无状态或有状态的,有状态的组件可与多种预定义上下文关联,如业务流程上下文或方法上下文,这为Seam赋予了...

    jbossseam eclipse安装 例子学习.doc

    通过上述步骤,我们已经完成了 Eclipse 开发环境中 JBoss Seam 的基本配置。这包括了 Eclipse、JBoss Application Server、JBoss Seam、JBoss Tools 以及 MySQL 数据库等组件的下载、安装与配置。这些步骤对于初次...

    Jboss Seam 三本最受欢迎的教材

    【JBoss Seam】是Java企业级应用开发框架,它整合了JSF(JavaServer Faces)、EJB(Enterprise JavaBeans)3.0、JPA(Java Persistence API)以及一系列其他技术,为开发人员提供了一个强大的全栈式解决方案。Seam...

    [JBoss] JSF & Facelets & JBoss Seam 核心技术 (英文版)

    [TipTec Development] JSF & Facelets & JBoss Seam 核心技术 (英文版) [TipTec Development] Essential JSF, Facelets & JBoss Seam (E-Book) ☆ 出版信息:☆ [作者信息] Kent Ka Iok Tong [出版机构] TipTec ...

    深入浅出JBoss Seam.pdf

    ### 深入浅出JBoss Seam:整合与强化Java EE框架 #### 一、引言 JBoss Seam是一款基于Java EE 5.0的轻量级框架,它旨在简化企业级Web应用的开发过程,并增强应用的可扩展性和开发者的生产力。本文将详细介绍JBoss ...

    Beginning JSF2 APIs and JBoss Seam

    - **组件**:Seam中的组件是UI组件的扩展,可以包含行为逻辑。 - **转换器**:用于在对象和UI组件之间转换数据。 - **验证器**:检查用户输入是否符合特定规则。 - **事件**:用于组件间通信,触发特定的动作或工作...

    jboss seam 教程

    ### JBoss Seam 教程知识点概述 #### 一、Seam简介与教程概览 - **Seam**:一个基于Java EE平台的应用框架,旨在简化企业级应用开发。 - **JBoss Seam**:由JBoss提供的Seam实现,提供了一系列功能强大的工具和...

    jboss seam 2.01GA REF DOC

    ### JBoss Seam 2.01GA REF DOC #### 引言:JBoss Seam概览与功能介绍 JBoss Seam 是一个为简化企业级 Java 应用开发而设计的框架。它结合了 JavaServer Faces (JSF)、Java Persistence API (JPA) 和 Java ...

    百度地图API在JBoss Seam中的研究与应用.pdf

    在本文“百度地图API在JBoss Seam中的研究与应用”中,作者探讨了如何将百度地图API集成到JBoss Seam应用程序框架中,以构建弱电管道管理系统。JBoss Seam是一个强大的框架,它集成了EJB(Enterprise JavaBeans)、...

    JBoss_Seam--中文教程

    ### JBoss Seam中文教程知识点详解 #### 一、JBoss Seam 的产生背景及意义 - **背景概述**:JBoss Seam 是一款旨在简化企业级Java应用程序开发的深度集成框架。随着Java EE生态系统的不断发展,越来越多的技术框架...

Global site tag (gtag.js) - Google Analytics