JEE6 CDI(Contexts and Dependency Injection)介绍

    Java EE 6已经发布了很久,不过国内使用的人依旧很少,资料也很缺乏。我自己本人很看好JEE6,觉得 JSR299- Contexts and Dependency Injection 很好很强大。CDI 也就是上下文依赖注入,概念和 Spring 中的 依赖注入(DI) 一样。在JEE6中被作为一个规范后,我们使用起来就更加的方便实用了。

    CDI最给力的一点就是提供了一个 Extension接口, 允许我们对CDI进行扩展。我们可以通过实现这个接口来做实现很多非常酷的功能。包括对 Bean 的注入前后的拦截,Bean执行构造方法前后的拦截等等。通过这些我们就可以实现事务,日志等等一些功能。

    目前实现 JSR-299 CDI 规范的框架有三个:  JBoss Weld   Apache OpenWebBeans 和 Caucho CanDI 。JSR-299 CDI 是 Gavin King 领导制定的,Weld 的实现也基本是由 JBoss的人员完成,所以JBoss社区比较活跃。

    CDI 作为一个依赖注入的规范,它的主要的优点有下面几点:

  • 类型安全:CDI不在通过字符串名称来注入对象,而是java类型来确定被注入的对象。当单单通过java类型还不能确定到底哪一个对象被注入的时候,你可以通过扩展 @Qualifier  注解来限定你需要注入的对象

  • 普通的Java Bean :在CDI中基本上所有的 Java Bean 都可以被注入。当然包括:EJB、JNDI资源、持久化单元、持久化上下文、接口等等。

  • 可扩展性:就像上面说到的,每一个 CDI 容器你都可以通过实现 Extension 接口来扩展一些功能。

  • 拦截器:CDI提供了一个十分方便的方法来实现拦截器功能。

  • 装饰器:装饰器可以让你动态的扩展或者重写现有的业务接口。这个功能十分方便,在CDI中,你在调用一个接口的实现类的时候,无须关系这个实现类的名称,所以在你更换新的实现的时候无需去修改你的代码,只需要在新的接口上面通过装饰器声明你要替换的之前的接口实现,然后在 Bean.xml 中声明一下即可。

  • 事件:CDI 提供了一种松耦合性的事件发送和接受机制。比如,在用户登陆后,我们需要在Session中存放一些用户信息。有了这个机制,我们不需要在登陆的那个方法中 通过new一个Session范围的对象或者把一些数据放入Session中,这样修改这些方法的时候,我们就得去修改这个登陆方法的。或者说 我们突然需要在用户登陆后,额外做一些事情,我们又得去修改登陆这块的代码。  在CDI中,我们可以在登陆成功后,发送出一个登陆成功的事件,然后我们可以在任何类中来接受这个事件,来完成对应的工作。 是不是很酷 :-)

  • EL表达式的扩展:CDI中默认支持EL表达式并对其进行了扩展,比如在JSF中,默认是不支持EL表达式传参的,如果结合CDI,那么就可以在EL表达式中传参数给后台Bean。

    就目前而言,CDI还是很JSF结合使用的比较多,当然也有 Zk-CDI 等一些前端框架的扩展,也可以通过对CDI的扩展也可以实现类似于Spring-MVC 结合JSP使用。对于国内依然是Spring+JSP的天下,对于我这样一直在使用JSF的人来说很是无奈。我本人一直觉得JSF的开发效率要比JSP高,对于普通的开发人员只需掌握JSF即可,不过前提需要一个成熟的框架。国内很多java web开发者对JSF 都比较排斥,目前JSF已经2.2了,以前的许多问题都已经解决,在看看Primefaces, RechFaces 这些强大的控件库。我觉得 JSF 已经值得我们去学习使用了。

    开始 CDI

    我们开始搭建一个CDI的工程,下载 Eclipse3.7.2 ,然后安装对应的 JBossTools 插件,然后下载 JBoss-as-7.1.0.Final 。JBoss As里面已经集成了 JSF,Weld模块,所以使用Jboss作为服务器是十分方便的。

    创建一个 Dynamic Web Project 3.0 的工程,然后为工程添加 CDI 的支持。添加CDI的支持是为了能够在EL表达式中Eclipse可以有代码提示。这样我们就搭建好了 Weld+JSF的工程,很方便吧 :-)

    编写Action代码:

import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@Named
@RequestScoped
public class HelloCDIAction {

	public String getHelloWord(){
		return "Hello Word";
	}
}

编写JSF页面代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"> 

<h:head></h:head> 
<body> 
	<h:outputText value="#{helloCDIAction.helloWord}" />
</body> 
</html>

然后部署,访问 http://localhost:8080/CDIDemo/Main.face 

 JEE6 CDI(Contexts and Dependency Injection)介绍

    后面会继续写一些有关 CDI 介绍的文章,结合JSF + Primefaces 给出一些 Demo。 

你可能感兴趣的:(CDI,JEE6)