CDI Features

EL/SpEL

1、EL语言(CDI与表达式语言(EL)集成,允许在JavaServer Faces页面或JavaServer Pages页面中直接使用任何组件)

1)概述;
EL是JSP内置的表达式语言,用以访问页面的上下文以及不同作用域中的对象 ,
取得对象属性的值,或执行简单的运算或判断操作。EL在得到某个数据时,会自动进行数据类型的转换。
使用EL表达式输出数据时,如果有则输出数据,如果为null则什么也不输出。

2)语法:
a.EL表达式总是放在{}中,而且前边有一个$作为前缀:${}
b.获取对象的属性值可以直接通过“对象.属性名”:${user.name};
注意:这里的属性名是get和set方法对应的属性值,并不是对象中的变量名。
c.获取对象的属性也可以通过“对象[“属性名”]”:${user["name"]}
d.获取Map中属性时可以以直接通过属性的key:${map.key},${map[key]}
e.在指定域中获取属性:
在EL表达式中如果我们直接使用属性名如:${user},它将会在四个域中由小到大依次查找。
顺序:pageScope、requestScope、sessionScope、applicationScope。
也可以指定从哪个域中获取:
${ pageScope .user }:当前页面
${requestScope.user}:当前请求
${sessionScope.user}:当前会话
${sessionScope.user}:当前应用

3)EL中包含11个隐含对象,这些对象可以在EL表达式中直接使用:
a.pageContext,和JSP中的pageContext功能一样
b.请求域:pageScope/requestScope/sessionScope/applicationScope
c.请求参数,参数对象主要用于获取get或post请求中的参数:
param:获取指定的请求参数,${param.username}
paramValues:获取请求参数数组,如:${paramValues.sport[1]}
d.其他:header/headerValues/initParam/cookie

4)EL支持数学运算和逻辑运算:
a.加减乘除:${17+5} => 22
b.取余%或mod:${17%5} => 2
c.比较运算符>,<,==,!=,<=,>=,eq,ne,lt,gt,le,ge:${3>5}或${3 gt 5} =>false
d.逻辑比较 &&或and,!或not,||或or,empty:${!true} => false

上下文

要完全了解什么是上下文,我们首先需要明白web应用是怎样运行的。现代计算机应用是可对话性质的,用户发送请求开始启动应用,传入一些预定的数据单元,直到最后一个预先定义的工作完成,请求会接收到反馈输出。这一过程中在计算机和终端用户之间存在着一些来回往复,计算机应用程序与用户必须进行多次交互,积累和处理数据直到它可以构造出所期望的输出。应用程序必须维护当前用户的数据状态,直到应用程序终止,这种类型的应用被认为是“有状态的”。Web应用程序使基于HTTP写的,HTTP其本身是无状态的,它是一种请求/响应协议,其中事务的状态只有在一个请求的处理过程中是活跃的。JEE服务器通过提供数据结构保存有状态的数据来确保应用的“有状态性”。当web应用程序使用Servlet规范,应用程序生命周期是可实现的,在生命周期的不同部分,有一些明确定义的数据的范围,我们称之为上下文,具体包括:

Application - 应用程序上下文,即数据在应用程序上下文中可用。换句话,数据在应用程序部署到应用程序卸载或删除这段时间可用。这是最高级别的上下文。
Session - 会话上下文,即数据存储在会话中,数据只有在会话被某一用户创建到会话被移除这段时间内被这个用户可用。
Request - 请求上下文,数据只有在同一个用户的同一个请求中可用,当请求返回,数据不再被服务器维护。
Conversation - CDI新增加的上下文,它的作用范围是同一个会话上下文的几个请求的总和。如下图所示为Conversation示意图:

依赖注入

组件不做定位查询,只提供普通的Java方法让容器去决定依赖关系。容器全权负责的组件的装配,它会把符合依赖关系的对象通过JavaBean属性或者构造函数传递给需要的对象。通过JavaBean属性注射依赖关系的做法称为设值方法注入(Setter Injection);将依赖关系作为构造函数参数传入的做法称为构造器注入(Constructor Injection)。

Spring通过DI(依赖注入)实现IOC(控制反转),常用的注入方式主要有三种:构造方法注入,setter注入,基于注解的注入。

其他CDI的特性

除了上下文和依赖注入外,CDI还提供了一些其他特性:

EL表达式的扩展:CDI中默认支持EL表达式并对其进行了扩展,比如在JSF或JSP中,默认是不支持EL表达式传参的,如果结合CDI,那么就可以在EL表达式中传参数给后台Bean。
拦截器:CDI提供了一个十分方便的方法来实现一个或多个拦截器,用来处理 cross-cutting concerns such as logging
装饰器:装饰器可以让你动态的扩展或者重写现有的业务接口。这个功能十分方便,在CDI中,你在调用一个接口的实现类的时候,无须关心这个实现类的名称,所以在你更换新的实现的时候无需去修改你的代码,只需要在新的接口上面通过装饰器声明你要替换的之前的接口实现,然后在 bean.xml 中声明一下即可。
事件:CDI 提供了一种松耦合性的事件发送和接受机制。比如,在用户登陆后,我们需要在Session中存放一些用户信息。有了这个机制,我们不需要在登陆的那个方法中 通过new一个Session范围的对象或者把一些数据放入Session中,这样修改这些方法的时候,我们就得去修改这个登陆方法的。或者说 我们突然需要在用户登陆后,额外做一些事情,我们又得去修改登陆这块的代码。 在CDI中,我们可以在登陆成功后,发送出一个登陆成功的事件,然后我们可以在任何类中来接受这个事件,来完成对应的工作。
类型安全:CDI不在通过字符串名称来注入对象,而通过java类型来确定被注入的对象。当只是通过java类型还不能确定到底哪一个对象被注入的时候,你可以通过扩展 @Qualifier 注解来限定你需要注入的对象。
注解:CDI中所有的注入都是通过注解来完成的,XML相关的配置非常少
普通的Java Bean :在CDI中基本上所有的 Java Bean 都可以被注入。当然包括:EJB、JNDI资源、持久化单元、持久化上下文、接口等等。

原文地址:https://www.cnblogs.com/ting-3/p/10708909.html