本 部 分 讲 述 @Alternative和 @Qualfiers
1. 使 用 @Alternative来 选 择 一 个 替 代 者
你 可 能 还 记 得 ,我 们 在 前 面 定 义 了 几 个 可 作 为 替 代 选 择 的 传 输 器 ,分 别 是 JsonRestAtmTransport和 SoapRestAtmTransport。 想 象 一 下 如 果 你 是 ATM的 安 装 者 ,那 么 需 要 配 置 传 输 器 和 地 点 。 我 们 之 前 定 义 的 注 入 点 只 是 使 用 默 认 传 输 器 StandardRestAtmTransport。
如 果 还 需 要 不 同 的 传 输 器 ,就 需 要 更 改 /META-INF/beans.xml文 件 来 正 确 的 选 择 传 输 器 ,如 下 :
例 1. {classpath}/META-INF/beans.xml
xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
你 在 输 出 中 将 会 看 到 选 择 使 用 了 JSON REST传 输 器 。
Output
deposit called
communicating with bank via JSON REST transport
替 代 选 择 在 DI中 是 非 常 普 遍 的 场 景 应 用 ,也 就 是 说 ,你 有 不 同 的 注 入 对 象 依 赖 于 不 同 的 构 建 环 境 。 很 棒 的 是 对 象 可 以 被 替 换 。 替 代 选 择 特 性 允 许 你 标 记 对 象 可 以 被 其 它 对 象 替 换 。
如 果 DI容 器 有 选 择 替 代 功 能 ,可 以 让 你 标 记 对 象 能 够 被 替 代 。 请 考 虑 使 用 这 种 方 式 。 因 为 我 们 不 需 要 非 得 在 文 档 中 说 明 替 代 选 择 ,他 自 身 就 是 一 种 文 档 ,如 果 某 些 人 知 道 CDI并 且 知 道 替 代 选 择 ,那 么 他 们 在 看 到 它 时 不 会 感 到 陌 生 。 替 代 选 择 是 让 你 替 代 对 象 的 标 准 方 式 。
你 可 以 考 虑 使 用 CDI作 为 很 多 模 式 的 标 准 ,我 们 已 经 在 很 多 纯 DI框 架 中 使 用 过 。 简 单 化 和 标 准 化 是 DI的 发 展 方 向 的 一 部 分 。
2. 使 用 @Qualifier注 入 不 同 的 类 型
在 CDI中 所 有 的 对 象 和 生 产 者 都 是 限 定 类 型 的 。 如 果 你 没 有 分 配 限 定 类 型 那 么 将 会 使 用 默 认 的 @Default和 @Any。 就 像 一 个 罪 犯 在 美 国 ,如 果 没 有 足 够 的 钱 给 律 师 ,那 么 他 将 会 被 分 配 一 个 。
限 定 类 型 用 来 识 别 正 确 的 对 象 被 注 入 ,你 可 以 写 自 己 定 制 的 限 定 类 型 。
限 定 类 型 能 够 匹 配 注 入 目 标 和 注 入 源 ,确 保 正 确 的 类 型 被 注 入 。
你 可 以 决 定 在 什 么 时 候 注 入 Soap、 Json和 Standard传 输 器 。 你 不 想 把 他 们 列 出 来 选 择 ,实 际 上 ,你 想 在 某 些 时 候 使 用 Json实 现 .
下 面 是 对 于 Soap的 一 个 限 定 类 型 定 义 。
例 2. Soap运 行 时 限 定 类 型 注 解
package org.cdi.advocacy;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import javax.inject.Qualifier;
@Qualifier @Retention(RUNTIME) @Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface Soap {
}
注 意 一 个 限 定 类 型 就 是 一 个 运 行 时 注 解 ,其 标 注 了 @Qualifier注 解 。 @Qualifier注 解 把 一 个 运 行 时 注 解 声 明 为 限 定 类 型 。
下 面 我 在 SoapAtmTransport使 用 一 个 新 的 限 定 类 型 @Soap:
例 3. SoapAtmTransport使 用 新 的 @Soap限 定 类 型 注 解
package org.cdi.advocacy;
@Soap
public class SoapAtmTransport implements ATMTransport {
@Override
public void communicateWithBank(byte[] datapacket) {
System.out.println("communicating with bank via Soap trans