当前位置:

首页 > 编程开发 > CDI限定符解决接口注入歧义方法

CDI限定符解决接口注入歧义方法

本文旨在解决在使用CDI(ContextsandDependencyInjection)时,由于接口存在多个实现类而导致的注入歧义问题。通过引入CDI限定符,我们将学习如何明确指定需要注入的实现类,从而避免注入失败,并确保应用程序的正确运行。文章将提供详细的代码示例和步骤,帮助读者理解和应用CDI限定符,提升CDI开发技能。

本文目录

    使用 CDI 限定符解决接口注入歧义问题

    本文旨在解决在使用 CDI(Contexts and Dependency Injection)时,由于接口存在多个实现类而导致的注入歧义问题。通过引入 CDI 限定符,我们将学习如何明确指定需要注入的实现类,从而避免注入失败,并确保应用程序的正确运行。文章将提供详细的代码示例和步骤,帮助读者理解和应用 CDI 限定符,提升 CDI 开发技能。

    在使用 CDI 进行依赖注入时,如果一个接口有多个实现类,CDI 容器将无法确定应该注入哪个实现类,从而导致注入歧义错误。 本文将介绍如何使用 CDI 限定符来解决这个问题,并提供详细的代码示例和步骤。

    理解 CDI 注入歧义

    在 CDI 中,Bean 是通过其类型和限定符来识别的。默认情况下,类型是从定义 Bean 的 Bean 类的传递类型闭包派生的(或者从定义 Bean 的生产者方法/字段的返回类型派生的)。

    例如,如果有一个接口 Hello,它有两个实现类 HelloImpl1 和 HelloImpl2,那么 CDI 容器会识别出两个具有以下类型的 Bean:

    • {Hello, HelloImpl1}
    • {Hello, HelloImpl2}

    如果没有使用任何限定符,当尝试使用 @Inject Hello hello 注入 Hello 接口时,CDI 容器会发现有两个符合条件的 Bean,因此无法确定应该注入哪个 Bean,从而导致注入歧义错误。

    使用 CDI 限定符解决歧义

    解决 CDI 注入歧义的正确方法是使用 CDI 限定符。限定符允许我们为 Bean 添加额外的标识信息,从而使 CDI 容器能够区分不同的 Bean。

    1. 定义限定符

    首先,需要定义一个自定义的限定符。限定符本身是一个注解,需要使用 @Qualifier、@Retention 和 @Target 元注解进行标记。

    import static java.lang.annotation.ElementType.FIELD;
    import static java.lang.annotation.ElementType.METHOD;
    import static java.lang.annotation.ElementType.PARAMETER;
    import static java.lang.annotation.ElementType.TYPE;
    import static java.lang.annotation.RetentionPolicy.RUNTIME;
    
    import java.lang.annotation.Retention;
    import java.lang.annotation.Target;
    
    import jakarta.inject.Qualifier;
    
    @Qualifier
    @Retention(RUNTIME)
    @Target({ TYPE, FIELD, METHOD, PARAMETER })
    public @interface MyQualifier {
    }

    在上面的代码中,@MyQualifier 是我们自定义的限定符。@Retention(RUNTIME) 表示该注解在运行时保留,@Target 指定该注解可以应用于哪些元素(例如,类型、字段、方法、参数)。

    2. 使用限定符标记 Bean

    接下来,需要使用自定义的限定符来标记需要区分的 Bean。

    import jakarta.enterprise.context.Dependent;
    import jakarta.inject.Named;
    
    @Dependent // this is just an example, use any scope you need or have been using
    @MyQualifier // specify qualifier of this bean
    @Named("HelloImpl1")
    public class HelloImpl1 implements Hello {
        // some very cool code
        @Override
        public String sayHello() {
            return "Hello from HelloImpl1";
        }
    }
    import jakarta.enterprise.context.Dependent;
    import jakarta.inject.Named;
    
    @Dependent // this is just an example, use any scope you need or have been using
    @Named("HelloImpl2")
    public class HelloImpl2 implements Hello {
        // some very cool code
        @Override
        public String sayHello() {
            return "Hello from HelloImpl2";
        }
    }

    在上面的代码中,HelloImpl1 类使用 @MyQualifier 注解进行标记,表示它具有 MyQualifier 限定符。

    3. 在注入点使用限定符

    最后,需要在注入点使用相同的限定符来指定需要注入的 Bean。

    import jakarta.inject.Inject;
    
    public class MyClass {
        // declare the injection point with qualifier(s)
        @Inject
        @MyQualifier
        Hello helloBean;
    
        public void doSomething() {
            System.out.println(helloBean.sayHello());
        }
    }

    在上面的代码中,helloBean 字段使用 @MyQualifier 注解进行标记,表示需要注入具有 MyQualifier 限定符的 Hello 接口的实现类。

    完整示例

    以下是一个完整的示例,演示如何使用 CDI 限定符解决接口注入歧义问题:

    // Hello.java
    public interface Hello {
        String sayHello();
    }
    
    // HelloImpl1.java
    import jakarta.enterprise.context.Dependent;
    import jakarta.inject.Named;
    
    @Dependent // this is just an example, use any scope you need or have been using
    @MyQualifier // specify qualifier of this bean
    @Named("HelloImpl1")
    public class HelloImpl1 implements Hello {
        // some very cool code
        @Override
        public String sayHello() {
            return "Hello from HelloImpl1";
        }
    }
    
    // HelloImpl2.java
    import jakarta.enterprise.context.Dependent;
    import jakarta.inject.Named;
    
    @Dependent // this is just an example, use any scope you need or have been using
    @Named("HelloImpl2")
    public class HelloImpl2 implements Hello {
        // some very cool code
        @Override
        public String sayHello() {
            return "Hello from HelloImpl2";
        }
    }
    
    // MyQualifier.java
    import static java.lang.annotation.ElementType.FIELD;
    import static java.lang.annotation.ElementType.METHOD;
    import static java.lang.annotation.ElementType.PARAMETER;
    import static java.lang.annotation.ElementType.TYPE;
    import static java.lang.annotation.RetentionPolicy.RUNTIME;
    
    import java.lang.annotation.Retention;
    import java.lang.annotation.Target;
    
    import jakarta.inject.Qualifier;
    
    @Qualifier
    @Retention(RUNTIME)
    @Target({ TYPE, FIELD, METHOD, PARAMETER })
    public @interface MyQualifier {
    }
    
    // MyClass.java
    import jakarta.inject.Inject;
    
    public class MyClass {
        // declare the injection point with qualifier(s)
        @Inject
        @MyQualifier
        Hello helloBean;
    
        public void doSomething() {
            System.out.println(helloBean.sayHello());
        }
    
        public static void main(String[] args) {
            // This part depends on your CDI container (e.g., Weld, OpenWebBeans)
            // Here's a simplified example using a hypothetical CDI container:
            MyClass myClass = CDI.current().select(MyClass.class).get();
            myClass.doSomething();
        }
    }

    注意事项

    • 确保限定符的 @Retention 设置为 RUNTIME,以便在运行时可以使用限定符。
    • 确保在 Bean 的声明和注入点使用相同的限定符。
    • 可以使用多个限定符来进一步区分 Bean。

    总结

    通过使用 CDI 限定符,我们可以解决接口注入歧义问题,并明确指定需要注入的实现类。 这可以提高应用程序的可靠性和可维护性,并使 CDI 注入更加灵活和强大。 建议阅读 CDI 规范,了解更多关于类型安全解析和限定符的信息。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发
    相关文章 更多
    码上飞电脑版快速访问:官方书签与网页入口管理
    码上飞电脑版快速访问:官方书签与网页入口管理

    码上飞电脑版可把https://www.codeflying.net/保存为Chrome书签,通过书签栏或管理器直接访问。本文演示添加书签、文件夹与单项管理,并说明起始页面的可选设置、旧链接检查和登录限制,避免把访问快捷方式误认为自动登录。

    码上飞登录反复失效怎么办:站点数据与会话检查
    码上飞登录反复失效怎么办:站点数据与会话检查

    码上飞登录反复失效时,先确认账号验证完成,并检查浏览器是否限制网站数据或退出时自动删除。本文按第三方Cookie、站点例外、设备端数据和单站清理的顺序排查,说明清理会退出账号及删除离线数据,适用于电脑Chrome。

    码上飞网页空白怎么办:浏览器脚本与站点权限排查
    码上飞网页空白怎么办:浏览器脚本与站点权限排查

    码上飞网页空白先检查网址、网络和刷新结果,再依次核对Chrome的JavaScript、站点权限与扩展拦截。本文给出当前中文设置路径、仅为官网设例外的方法,以及图片缺失和浏览器版本检查,避免一开始就清除全部数据或重置浏览器。

    码上飞帮助文档怎么进入:官方教程与问题查找
    码上飞帮助文档怎么进入:官方教程与问题查找

    码上飞帮助文档可从官网顶部或首页底部的帮助文档进入,官方链接指向码上飞帮助中心。本文说明如何按新手入门、常见问题及部署相关主题定位内容,区分文档平台登录与码上飞账号,并提供入口打不开时的处理方法。

    码上飞我的权益在哪里查看:额度与会员信息核对
    码上飞我的权益在哪里查看:额度与会员信息核对

    码上飞我的权益位于工作区侧栏,个人额度需在正确账号下查看;首页定价用于对比公开会员方案。本文区分会员能力、积分与邀请奖励,说明如何查看奖励记录及有效期,避免把公开套餐、默认数字或邀请列表当作本人权益已到账。

    码上飞账号设置与账单入口:如何核对真实登录状态
    码上飞账号设置与账单入口:如何核对真实登录状态

    码上飞账号设置与账单从工作区侧栏的设置和账单进入,账单、API服务与积分明细用途不同。本文说明如何核对本人身份、识别公开页面的默认显示,以及查看明细时应注意的字段,避免把空记录或默认积分当成真实账户结果。

    码上飞我的应用在哪里:搜索与发布状态筛选
    码上飞我的应用在哪里:搜索与发布状态筛选

    码上飞我的应用位于工作区侧栏,进入后可按全部、已发布、未发布筛选,并通过搜索应用查找项目。本文说明空列表的判断顺序、账号核对和筛选恢复方法,避免把未登录或筛选无结果误认为项目删除,适用于电脑网页。

    码上飞如何创建新应用:从需求描述进入开发流程
    码上飞如何创建新应用:从需求描述进入开发流程

    码上飞创建新应用可从工作区侧栏进入创建新应用,在需求框写清目标、使用者、数据和主要操作,再检查账号与额度后点击立即开发。本文说明如何组织首轮需求、区分新建与继续已有项目,以及未登录或按钮不可用时的处理。

    码上飞应用广场怎么用:分类筛选与案例预览
    码上飞应用广场怎么用:分类筛选与案例预览

    码上飞应用广场可从官网/my-home进入,先按用途选择分类,再用应用名称或功能关键词搜索。本文说明个人工具、企业服务、记账类结果和无结果状态的区别,以及预览、复制与个人应用归属的边界,适用于电脑网页端。

    码上飞邮箱注册教程:密码要求与首次验证流程
    码上飞邮箱注册教程:密码要求与首次验证流程

    码上飞邮箱注册从官网/register进入,填写本人邮箱、符合要求的密码和确认密码后,按继续进入后续验证。本文核对当前密码长度与组合条件,说明首次验证的完成判断、与手机号登录的区别,以及表单不能继续时的检查方法。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。