我刚刚向JCP提交了JSR-299(上下文和依赖注入),下载链接为此处[1]。我们正在为8月的最终发布做准备,以便在9月的Java EE 6发布时及时推出。感谢大家为此付出的辛勤努力!
如果您之前没有关注299,现在是了解的好时机。这可以说是EE 6中最重大的增强,提供了以下功能套件
- 一个完全通用的类型安全依赖注入模型,
- 可注入对象的上下文生命周期管理,
- 一个事件通知模型,
- 通过用户定义的注解进行拦截器绑定,
- 类型安全装饰器,
- 用于集成第三方Web或组件框架的完整SPI,以及
- 与JSF、servlets和JSP的集成,包括
- JSF的会话上下文
最好的是,这些功能提供了一种干净、简单、统一的编程模型,强调两个主要价值:类型安全和松散耦合。JSR-299不使用字符串或XML来连接bean、事件、拦截器和装饰器。相反,它使用Java类型系统和用户定义的“绑定注解”来发现松散耦合组件之间的关系。
现在是澄清一些我看到的错误观点的好时机。
JSR-299仅适用于EJB
这根本不是真的。
默认情况下,您可以在Java EE环境中注入几乎任何类型的东西,包括servlet、servlet过滤器、servlet事件监听器、JAX-WS Web服务端点和JAX-RS资源。更好的是,有一个SPI,任何第三方框架(例如,像Wicket这样的Web框架)都可以轻松请求299实现对框架管理的对象执行注入。
您可以注入的对象类型包括
- 管理Bean(普通Java类),
- 本地EJB会话Bean,
- 从生产方法或生产字段获取的对象,以及
- Java EE组件环境资源(数据源、连接器、持久上下文、JMS消息目的地、Web服务、远程EJB等)
如果你正在试图不相信我(你知道你是谁),这里有一个可以注入的类
final class Head {}
这是一个使用注入的类
final class Person { private Head head; @Initializer Person(Head head) { this.head=head; } }
还有一个简单的SPI,允许第三方框架(包括其他容器如Spring)通过299容器提供自己的对象以供注入。
JSR-299与JSF相关联
这也不正确。在EE 6环境中,JSR-299除了与JSF集成外,还预先集成了Java Servlets、JSP和JAX-RS。此外,299提供了SPI以启用与您喜欢的Web框架的集成。这些SPI使得将第三方Web框架与EE环境其他部分集成变得比以往任何时候都更容易。
JSR-299与重量级
Java EE容器相关联
显然,与Java EE环境集成对专家小组来说是一个极高的优先级,因此当你阅读规范时,你会遇到很多关于Java EE集成的信息。JSR-299定义的某些功能特定于某些其他EE技术。例如,如果没有EJB容器,我们无法注入EJB!但这并不意味着JSR-299仅适用于像JBoss或GlassFish这样的传统Java EE容器。
相反,299被设计成适合包含各种执行环境,例如
- Java EE 6为Servlet容器定义了一个Web配置文件,类似于Caucho Resin、JBoss Web平台或SpringSource dm服务器,这些服务器不想支持完整的EE 5技术集。建议Web配置文件将需要支持JSR-299。
- EJB 3.1定义了一个可嵌入容器,它在Java SE环境中运行。该可嵌入容器也将支持JSR-299。
然而,JSR-299目前没有定义一个用于在SE环境中独立启动和运行容器的引导API。相反,此API正在由JSR-330定义。与JSR-299不同,JSR-330没有定义编写可移植应用程序所需的全部内容。因此,如果您想将应用程序移植到其他容器实现,您仍然需要JSR-299。因此,我们计划发布JSR-299的维护版本,其中包含对JSR-330引导API的支持。目前,如果您想在SE环境中运行JSR-299,您需要使用特定供应商的引导API。
JSR-299使用了大量的注解
我们在简单用例中非常小心,不要求使用许多注解。以依赖注入为例。
几乎任何Java类都可以在容器中注入,而不需要在类上使用任何注解。大多数注入点需要一个注解来指示容器执行注入。容器使用注入点的Java类型来决定应该注入什么对象。
然后,在更复杂的情况下,仅凭对类型系统的了解不足以明确表达依赖关系时,容器可以使用额外的用户定义注解来解决歧义。好消息是,用户定义注解通常在应用业务逻辑方面表达有意义的内容。因此,它们提高了代码的可读性。
例如,这既不类型安全,也不易读
@PersistenceContext(unitName="userDB") EntityManager em;
所以,在JSR-299中,你可以这样写
@UserDatabase EntityManager em;
拦截器绑定和事件观察,以及装饰器绑定(装饰器绑定是依赖注入的特殊情况)遵循非常相似的模型。