`
WildFly
  • 浏览: 63925 次
社区版块
存档分类
最新评论

展望CDI 2.0规范

阅读更多

本文译自 http://www.next-presso.com/2014/03/forward-cdi-2-0/

 

作者Antoine Sabot-Durand是红帽软件工程师,CDI规范专家组成员,本文提出了对未来的CDI 2.0规范想法,体现了作者对于组件运行的本质思考,是难得的好文。

 

不过估计写成此文时一气呵成,所以有些笔误和未达意之处。我翻译的也比较急,难免有错误之处,敬请谅解。


 

====== 以下为译文  =========


CDI可能是在JavaEE中最容易被忽略的规范之一。4年前1.0版本发布时,CDI是作为"JavaEE的扩展点“出现的。从技术来说它的确如此,但是并不是所有JavaEE的JSR都完全采用CDI,来提供一致的编程体验。今天IT世界快速发展,经过很多年使用巨大内存和多核的技术方案,我们又回归到原来需要优化资源使用的日子,面向移动或者嵌入式平台开发。由于CDI可以在JavaEE之外使用,所以它可以在新的方案里成为有趣的一个角色。但在此之前,它应该继续演进,并为这个新的挑战做好准备(并继续推进在JavaEE中越来越重要)。在这篇文章中我将尝试分享我的想法,CDI应该如何演变来满足未来的需求。我会探讨新的功能特性,使用一种更加模块化的体系结构,来使CDI可以容易扩展,从小型的树莓派设备到大型的集群方案。


声明:由于我会领导CDI 2.0规范(和Pete Muir一起),需要强调这篇文章都是我个人的观点,而不代表CDI 2.0的官方内容,或者是红帽软件CDI专家组的任何看法。

我想看到的新特性

一些特性已经被专家组讨论了,有些没有加入到1.1的推迟到2.0版本。有些是第三方开发的内容(主要是Apache的Deltaspike)规范标准化,有些是全新的。无论如何,大部分观点都很重要,可以帮助第三方项目或者JSR来促成最佳的CDI规范。

在JavaSE中启动

如今每一个CDI实现都提供一种方式来在JavaSE或者简单服务器环境(如仅包括Servlet)中启动CDI,Apache Deltaspike有一个通用的解决方案来做到这个。现在可以考虑把CDI规范集成到JavaSE中了。

容器热交换

强类型注入非常有用,但我认为CDI这方面太严格了。为了支持动态JVM语言,我们应该能够触发BeanManager重新启动来加载更多的bean,比如提供API来启动一个新的CDI容器来扩充内容。如果启动顺利,通过更多的步骤在新的容器中来复制状态和存在的实例,并保留旧容器的垃圾存在现状。这样在出错的情况下,我们可以保存当前的BeanManager。这是一个代价比较大,但是非常有用的特性,特别是对于一些高级工具或者特定功能的应用系统(比如CMS,电子商务平台等)

轻量级CDI

正如之前谈到的,业界希望能让CDI运行在嵌入式系统中,如树莓派,Arduino,乐高积木Mindstorms或者Android。如今大量使用Proxy阻碍了这个方向。

Java Proxy在2000年时非常有用,但现在这项技术太老了,带来很多问题(巨大的堆栈跟踪,JVM优化,高资源消耗等),现在CDI规范也想当然的未来代理用在实现之中。

这样看来,有一个好的方案是提供一个CDI规范子集,更少的限制,更加轻量。我们可以称之为“CDI Lite”(类似EE6中的EJB Lite)。这个子集会包括DI的所有内容,但可能去除所有和上下文(Context),Interceptor(拦截器),Decorator(装饰器)等内容。

也有讨论如何在不移除特性的情况下让CDI更轻量一些。

再见Proxy,欢迎Annotation和InvokeDynamic

另一个方法是在CDI实现中找到其他方案来替换Proxy,现在我们有两个选择:

  • Annotation处理:编译时就对annotation进行处理,生成静态“magic"注入/装饰代码,类似于Dagger。
  • InvokeDynamic:运行时进行链接,可以提供类似Proxy的行为,而较少的缺陷和可能有更好的性能。对于第二种方法,我开始做一些研究,希望很很快提供概念验证方案。


XML 配置文件

现在是提供这个功能的时候了。现存方案中使用扩展点来提供这个特性,但这个应该是核心功能,可以用于在部署时定义如何注册Bean和Annotation的重新载入,所以应该在规范中定义。如果CDI能够在其他规范中越来越适用,那么这个XML定义可能会成为通用的JavaEE配置文件格式的入口点!

如今,一些框架比如ApacheCamel不能使用CDI,就是因为没有配置方案,所以提供这个能力会扩展其应用范围。

异步的消息和事件

现在是Vert.x和Node.js异步处理的时代(我们想象一下:回调)。可以通过使用并发包在规范中进行定义。我们将提供一种方法来支持异步调用,无须用EJB的异步调用和异步事件方式,比如在@Observes加入一个异步boolean项,并且提供可选项来处理回调。

支持@Startup

加入一个简单功能:CDI bean在初始化阶段以后就自动完成实例化步骤,就和EJB目前的差不多。

这是一个开发者普遍的需求,而并不难做到。

可移植扩展API的推广和简化用法

 

 

我认为可移植扩展API是CDI中最好的特性。当然Ioc,事件和上下文管理都是很棒的,但它们在CDI 1.0引入时并不是最新的概念。

而可移植扩展API完全是CDI的创新,加入到JavaEE DNA中,可以无须使用私有方法就可以自然的扩展。

我认为这一点没有被推广很可惜(CDI的缩写中也没有体现其想法),内容还被放置在规范文本的结尾处,无视很多项目和规范可以从中收益。

我的分析是,缺乏和很多复杂概念项目进行沟通,难以深入到扩展的开发之中。我们也许可以提供更高的简化层来容易上手来开发扩展。不要误会我的意思,现有的机制是很好的,可以继续保留(可以增强),但我们可以提供辅助工具来更容易的创建扩展。可以是以下几种:

  1. Deltaspike AnnotationTypeBuilder和BeanBuilder标准化,使得创建Bean更容易。
  2. 针对类型和annotation的自省工具。
  3. 更简单的方法来创建新的和扩展已有的作用域。我们鼓励其他规范重用现有作用域(如@RequestScoped)的生命周期,但只能在实现层上做到这一点。


我们还应该特别注意初始化过程中的第一个事件(直到AfterTypeDiscovery)。因为CDI还不知如何处理类型和Annotation元数据的修改。这些未来会成为JavaEE配置系统的一部分。

事件执行顺序化

在CDI 1.1中,通过@Priority定义了装饰器和拦截器的优先顺序。是否也可以用在订购事件上?在@Observes上使用@Priority不是个好注意,因为这个annotation来自拦截器包中,我们可以在@Observes加入priority字段。

去除对Producer和Custom bean的偏见

为什么Producer和Custom bean是CDI的二等公民?我希望能够用装饰器或者拦截器在Producer上,或者至少有API让我能做到这一点。

扩展事件的作用域范围,从包到整个服务器

让CDI事件总线运行在JavaEE世界中更高的层次上,这样可以选择事件的传播范围,是当前应用程序,当前模块(EAR),当前包,或者是其他所有程序都侦听这个事件。

瞬态注入

当把一个依赖bean注入到一个长期存在的bean时,后者初始化时这个注入完成并只执行一次。如果我想每次访问时都再次初始化并且重新注入时(如我在Agorava项目遇到的情况),现在我必须这样写:

@Inject Instance<MyBean> myBeanInstances;
public Mybean getMyBean() { return myBeanInstances.get(); }

 

我希望以后可以这样写:
@Inject @Transient MyBean myBean;

这是个语法糖,但这种写法易写易读。我们可以试着再找一些例子来说明代码如何简化。

更方便的流式查询语法

实现<T>接口的实例和编程时查询都是很有用的,但有时候非常繁琐,特别是处理Qualifiers时。

这个可以通过提供工具和用Java8的类型注解,来生成qualifier来简化,为什么不采用查询DSL?

myBeanInstance.restrictedTo(BeanImp.class).withQualifier(new @MyQualifier("Binding") AnnotationLiteral<>(), new @MyOtherQualifier AnnotationLiteral<>()).select();

 

是不是看上去友好些?

监控设施

还记得Seam2时优秀的调式页面么?我想有同样的东西或者工具来轻松构建相同的功能,监视bean和运行范围。CDI很神奇,可以有很好的工具来查看所有的内容,bean的成本,上下文和我们部署的拦截器。

更好的模块化支持:新的CDI架构(JavaEE)?

 

 


很多JSR都在抱怨CDI规范定义像铁板一块,和它们比较,实现很庞大(他们不想依赖更大的东西)。这个和缺乏JavaSE的引导支持,可能是CDI集成难以走远的2个主要原因。因此,我们可以提供一个更加模块化的方法,收集所有的模块,使用和JavaEE之外一致的代码栈。我理想中的JSR/模块是这样:

容器

容器模块存储所有应用程序用到的bean,作为独立模块提供以下功能:

  • 提供最小化的api/实现给客户端程序,通过JNDI来或者bean
  • 提供机制来加入插件到容器中,以支持新的组件(Servlet, JPA Entity, Guice, Spring bean)
  • 准备成为未来JavaEE的通用容器


事件总线

事件和观察者模式是CDI规范的强大功能,但它们同样可以用于CDI以外。

我们可以设想一个新的规范或者是CDI的一个模块,基于CDI事件总线,来给JavaEE提供更广泛的事件模型。一个API只能依赖半打类(如果我们增加异步处理,排序和事件作用域会更多)来做工作。

组件扫描和扩展引擎

现在每个规范都在启动时进行类的扫描。一般来说应用服务器都是用专有的方式做扫描工作,这个过程可以标准化,通过扫描阶段性事件和元数据的操作,这样我们可以提供一致体验和一个标准的方法来扩展JavaEE。 CDI已经提供了大多数此功能与初始化机制,允许“观察”现有类的部署和修改这些类(即注解)的元数据。

如果ProcessAnnotatedType事件可以在服务器层级被捕获,并允许放置"veto"到给定的servlet或者一组JPA entity上面?这个特性让我们做到单一容器和单一配置文件,这个特性是很多开发者梦寐以求的。

基本的DI

这个模块包括所有的简单注入的API。所以有@Inject, @Qualifier, Instance<>, @Producer, InjectionPoint和反射相关的,就是我说过的"CDI Lite"

上下文管理

Context是CDI一个很好的功能,但大家都不需要,应该放在一个可选的API包中。处理所有正常的范围上下文和复杂的生命周期管理。

拦截器和装饰器

如今拦截器已经有了自己的JSR,加入装饰器到其中会让其更完备。


结论:CDI需要你!

以上是我对CDI的个人愿望清单,你也许有你自己的。我并不知道这些是否是好的想法,是否都可行,我们需要帮助来完成未来的CDI 2.0。 如果你想愿意,敬请关注CDI上的官方网站,@cdispec Twitter帐户(或者我的)和这个博客,并给我们反馈,通过CDI Maillist或CDI的IRC频道(freenode上jsr346)。未来几个月会决定CDI(和Java EE)的未来。

 

 

0
1
分享到:
评论

相关推荐

    CDI规范Contexts and Dependency Injection for Java 2.0

    《Contexts and Dependency Injection for Java 2.0》(CDI 2.0)是Java开发中的一个核心规范,它提供了上下文管理和依赖注入的功能,旨在简化企业级应用的复杂性,提高代码的可测试性和可维护性。该规范由Antoine ...

    cdi-deltaspike-demo:CDI 2.0演示(焊接3)+ DeltaSpike数据+ JUnit 5 +嵌入式H2

    Weld 3是Weld的第三个主要版本,它不仅实现了CDI 2.0规范,还包含了一些额外的特性和性能优化。Weld 3提供了更强大的调试工具,更好的类型安全性和更快的启动时间,使得开发和部署基于CDI的应用更加高效。 ...

    cdi-training:存储我们CDI培训资源的资源库

    完成任务后,人们应该能够理解CDI 2.0规范的主要概念,并在实时应用程序中使用CDI 2.0概念。 该应用程序基于 规范和应用程序服务器。 涵盖的CDI基础知识 此示例涵盖了以下CDI概念 注射 范围 初始化(@ @...

    cdi-api-2.0.SP1.jar

    CDI (以前称为JSR 299)是一种尝试描述依赖注入的... 乍一看,CDI的吸引力在于SpringSource和Google都参与了规范团队。 CDI是Java EE 6堆栈的一部分,这意味着在Java EE 6兼容容器中运行的应用程序可以立即利用CDI。

    Pro CDI 2 in Java EE 8

    《Pro CDI 2 in Java EE 8》这本书深入探讨了Java企业版8中的Contexts and Dependency Injection(CDI)2.0规范,它是Java应用中管理组件和服务的核心技术之一。CDI允许开发者以声明式的方式管理对象的生命周期和...

    CDI , JSF2.0 项目兼容性问题总结

    在开发Java EE应用程序时,尤其是使用CDI(Contexts and Dependency Injection)和JSF(JavaServer Faces)2.0版本的项目,可能会遇到各种兼容性问题。本文将针对在WebSphere 8.5环境下遇到的一些典型问题进行总结,...

    CDI通信接口规范

    CDI(Content Delivery Interface)通信接口规范是一套用于系统间通过SOAP协议以XML格式进行信息交换的标准。此规范详细规定了消息传输的格式和内容,确保了数据交换的准确性和高效性。 首先,CDI规范定义了接口的...

    JavaEE6 CDI规范的使用1

    JSF(JavaServer Faces)在早期版本中已经引入了对管理bean的注解支持,但在JSF 2.0规范即将完成的同时,JSR 299(后来成为JSR 346)被提出,这便是CDI规范。CDI提供了比JSF更强大、更灵活的bean管理和依赖注入机制...

    Apress.Pro.CDI.2.in.Java.EE.8.pdf

    In Pro CDI 2 in Java EE 8, use CDI and the CDI 2.0 to automatically manage the lifecycle of your enterprise Java, Java EE or Jakarta EE application’s beans using predefined scopes and define custom ...

    JSF2 规范的标准参考实现

    6. **CDI集成**:JSF 2与Contexts and Dependency Injection (CDI)框架紧密集成,提供了更强大的依赖注入功能,便于管理组件和服务。 7. **Facelets作为默认视图技术**:Facelets取代了JSP成为JSF的默认视图表示...

    Mojarra JSF2.0库文件

    7. **CDI(Contexts and Dependency Injection)集成** - JSF 2.0集成了CDI,提供了依赖注入功能,使得组件之间可以方便地共享服务。 8. **Ajax支持** - 自带的Ajax库PrimeFaces或RichFaces可轻松实现异步更新,增强...

    OMA DRM Specification V2.0

    OMA DRM(开放移动联盟数字版权管理)规范V2.0是移动通信领域的一个关键标准,主要用于保护和管理数字内容的版权。这个规范在2006年3月发布,旨在提供一个统一的框架,使得内容提供商和服务提供商能够在各种移动设备...

    JSF2.0源代码

    5. **CDI集成**:JSF 2.0与Contexts and Dependency Injection (CDI)框架集成,使得依赖注入更加方便,增强了组件的可测试性。 6. **Partial State Saving**:部分状态保存策略可以减少服务器内存使用,提高性能。 ...

    javaee-cdi:关于JavaEE CDI规范的回购

    CDI规范旨在简化Java EE应用的组件管理和依赖管理,使得开发者可以更加专注于业务逻辑,而不是繁琐的对象创建和管理。 CDI的核心概念包括: 1. **依赖注入(Dependency Injection, DI)**:这是CDI的核心特性,...

    JSF 2.0 (Mojarra 2.0.2-FCS)

    JSF 2.0与Contexts and Dependency Injection (CDI)进行深度集成,使得依赖注入更方便,增强了组件化开发的能力。 8. **Faces Flow**: Faces Flow是JSF 2.0引入的一个新特性,用于管理复杂的对话流程,提供更好...

    JSF2.0基本环境

    - JSF2.0是Java EE 6规范的一部分,它提供了一个声明式的方式来创建用户界面,简化了Web开发。 - JSF2.0引入了Facelets作为默认的视图描述语言,替代了JSP,使页面结构更加清晰,代码更易于维护。 - 新增了...

    JavaServer Faces API (2.0)

    9. ** 集成CDI (Contexts and Dependency Injection)**:JSF 2.0与Java EE 6中的CDI集成,使得开发者可以利用CDI的强大功能,如依赖注入、拦截器等。 10. ** 安全性**:JSF 2.0提供了基本的安全框架,如对HTTP参数...

    jsf2.0实例

    - **CDI集成**:JSF 2.0与Contexts and Dependency Injection (CDI)框架紧密集成,简化了依赖注入。 - **Faces Servlet自动注册**:不再需要手动配置Servlet,简化了部署过程。 - **AJAX支持**:内置的PrimeFaces...

    jboss-seam2.0文档.rar

    **JBoss Seam 2.0:企业级应用开发框架** JBoss Seam 2.0 是一个全面的企业级Java开发框架,旨在简化Java EE(现在称为Java EE)应用程序的构建过程,尤其是在集成各种技术和处理业务逻辑方面。Seam 提供了一个统一...

Global site tag (gtag.js) - Google Analytics