`
billy_zh
  • 浏览: 61739 次
  • 性别: 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 Seam

    本书聚焦于JBoss Seam框架,旨在为读者提供一个全面、深入的理解,以掌握其在企业级应用开发中的应用与优势。 ### JBoss Seam框架概览 JBoss Seam是一个开源的应用框架,它基于Java EE标准,但通过引入一系列创新...

    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中文版

    本示例通过实现一个简单的消息列表功能,演示了Seam中组件之间的交互方式。 1. **代码理解**:逐行分析代码,帮助读者理解每个部分的作用和意义。 2. **工作原理**:探讨了Seam是如何管理和更新列表数据的,特别是...

    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 中文文档知识点概述 #### 一、JBoss Seam 简介 JBoss Seam 是一款基于 Java EE 的应用开发框架,它通过提供一套丰富的组件模型和灵活的应用结构,极大地简化了企业级应用的开发过程。Seam 结合了 ...

    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 ...

    深入浅出JBoss Seam

    作为Hibernate的创造者Gavin King的作品,Seam在设计之初就考虑到了ORM的最佳实践,它在整个Web交互生命周期中管理持久上下文,避免了DTO等技术的使用,提高了代码的整洁性和可维护性。 总的来说,JBoss Seam是一个...

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

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

    Practical JBoss Seam projects

    《实用JBoss Seam项目》是一本专注于介绍JBoss Seam框架及其在实际项目中应用的专业书籍。本书由Jim Farley编写,出版于2007年,是Java技术领域内的权威指南之一。JBoss Seam是一个开源敏捷的企业级JSF(JavaServer ...

Global site tag (gtag.js) - Google Analytics