Java EE 6依赖注入提供了统一的EJB与JSF编程模型

依赖注入是最近发布的Java EE 6中的一个主要特性,包含了JSR 330与299,他们都归属于Java EE中的企业应用技术类别。JSR 330(Dependency Injection for Java)为依赖注入提供了一个标准、可扩展的API。JSR 299(Contexts and Dependency Injection for the Java EE Platform 1.0)则建立在JSR 330之上,统一并简化了EJB与JSF编程模型。凭借JSR 299,Enterprise Bean可以充当JSF应用中的Managed Bean,同时为Web层带来了事务支持。

用于依赖注入的标准化注解

该规范的目标在于为依赖注入提供标准化、可扩展的API。JSR 330所定义的一套注解使得被注入的类能够在各种框架间移植,这样开发者就不会再深陷于特定于某个厂商的注解了,比如Spring和Google Guice等框架。该JSR提供的一些注解列举如下:

  • Inject:标识被注入的构造方法、方法以及属性。首先注入构造方法,然后是属性,最后是方法。此外,父类中的属性和方法会在子类前被注入。
  • Qualifier:标识修饰符注解。修饰符是强类型的元素,用于区分同一类型对象的不同使用方式,包括@Qualifier、@Retention(RUNTIME)以及@Documented注解。
  • Scope:标识范围的注解。
  • Singleton:标识某个类只会生成一个实例。
  • Named:这是一个字符串修饰符。

上下文与依赖注入

上下文与依赖注入(Contexts and Dependency Injection,即CDI)规范建立在JSR 330之上,该规范为依赖注入增加了很多功能,包括自动检测和注入类的配置,同时还提供了一个API用于在运行期定义新的注入类,这有助于集成第三方框架。

CDI统一并简化了EJB与JSF的编程模型。凭借CDI,Enterprise Bean可以在JSF应用中充当JSF Managed Bean的角色,同时为Web层带来了事务支持;Java EE组件(包括EJB)还可以绑定到生命周期事件上、也可以进行注入,还能够通过激发和观测事件以松耦合的方式进行交互。这样EJB组件就能够访问Web层的组件了,如Request、Session和Application Context等。

CDI有助于填平Java EE平台Web层与Enterprise层之间的沟壑。Enterprise层(借助于EJB和JPA等技术)对事务性资源提供了强大的支持,而Web层则关注于展示。Web层技术(如JSF和JSP等)会渲染用户界面并显示内容,但对于事务性资源的处理却显得捉襟见肘。CDI为Web层带来了事务支持,这样我们就能在Web应用中轻松访问事务性资源了。比如,借助于CDI,我们构建的Java Web应用能够轻松实现对数据库的访问(由JPA提供持久化支持)。

CDI建立在Java EE 6新引入的一个名为Managed Bean的概念之上,Managed Bean用于统一Java EE 6中各样各样的Bean。所谓Managed Bean,其实就是一个Java类,只不过Java EE容器会将其看作是受管理的组件。我们还可以在同一个命名空间下为其定义一个名字,就像EJB组件那样,不过这是可选的。Managed Bean还可以使用容器提供的一些服务,这些服务大多与生命周期管理和资源注入有关。其他的Java EE技术(如JSF、EJB等)和CDI都是建立在Managed Bean这个基本定义之上,只不过增加了额外的服务而已。比如,JSF Managed Bean增加了生命周期范围、EJB Session Bean增加了对事务的支持,而CDI则增加了对依赖注入的支持。在CDI中,Managed Bean就是个Java EE组件,其可以注入到其他组件中、关联到上下文中或是通过EL表达式访问。

CDI支持的服务提供了如下功能:

  • 有状态组件生命周期的改进,可以绑定到定义良好的上下文中
  • 类型安全的依赖注入方式
  • 借助于事件通知机制的交互
  • 可以将拦截器绑定到组件上(通过javax.interceptor.Interceptor和javax.interceptor.AroundInvoke注解)

我们可以通过javax.annotation.ManagedBean注解或是CDI注解(如范围注解和修饰符注解)声明一个Managed Bean。任何Bean都可以绑定到生命周期上下文中,都可以被注入,也都可以通过激发或是观测事件与其他Bean进行交互。此外,还可以在Java代码中直接调用Bean,也可以在标准的EL表达式中调用Bean。这样,JSF页面就可以直接访问Bean了,哪怕这个Bean是由EJB组件(如Session Bean)实现的也没有问题。

CDI提供的一些注解列举如下:

  • Model注解会在MVC架构下将某个Java Bean标识为一个模型对象。这是一个标准化的注解,标识在应用中某个类会担当特定的角色。
  • SessionScoped注解将某个Bean的范围设定为Session。除此之外,还有RequestScoped、ConversationScoped、ApplicationScoped以及Dependent注解。
  • Produces注解会将某个方法标识为生产方法,这样同一个系统下的另一个Bean如果需要该类型的对象就会调用这个生产方法。

JSR 299的一些参考实现项目有Apache OpenWebBeans、Resin CanDI以及JBoss Weld框架。请感兴趣的读者查看Sun开发小组发布的系列文章(第一部分、第二部分、第三部分)以深入了解JEE 6中的依赖注入特性。最近DZone还发布了一个关于CDI主题的图表。

查看英文原文:Dependency Injection in Java EE 6 Provides Unified EJB and JSF Programming Model

你可能感兴趣的:(Java EE 6依赖注入提供了统一的EJB与JSF编程模型)