如何在CDI中注解代理Bean使其不被视为接口类型Bean?
问题解答
核心思路:让代理类不被识别为MyInterface类型的可用Bean
不用局限于@Named,有多种方式可以让代理类不被容器当作MyInterface类型的Bean,下面是几种实用方案:
方案1:使用@Typed注解限定暴露类型
在Jakarta EE/Java EE的CDI规范中,@Typed注解可以指定Bean对外暴露的类型。给代理类加上该注解,只暴露它自身的类型,不包含实现的MyInterface:
@ApplicationScoped @Typed(MyInterfaceImplProxy.class) public static class MyInterfaceImplProxy implements MyInterface{ @Inject MyInterface myInterface; @Override public void doSomething() { myInterface.doSomething(); } }
这样容器只会将该类视为MyInterfaceImplProxy类型的Bean,不会把它归类到MyInterface的候选Bean列表中,自然就不会产生同接口多Bean的冲突。
方案2:移除代理类的Bean管理注解
如果这个代理类仅用于内部包装逻辑,不需要被容器管理为Bean,可以直接去掉@ApplicationScoped注解,将其改为普通类。在需要使用的地方手动实例化,或者通过工厂类创建,这样它就不会被容器识别为MyInterface类型的Bean。
方案3:用@Alternative标记为备选实现
如果代理类只是作为备选方案,平时不需要启用,可以给它加上@Alternative注解。默认情况下容器不会将其作为MyInterface的可用Bean,只有在beans.xml中配置启用后才会生效:
@ApplicationScoped @Alternative public static class MyInterfaceImplProxy implements MyInterface{ // 原有实现代码不变 }
然后在beans.xml中添加配置:
<alternatives> <class>你的包路径.MyInterfaceImplProxy</class> </alternatives>
这种方式适合需要在不同环境切换实现的场景。
关于@Named的补充说明
用@Named配合限定符确实能区分两个Bean,但这属于解决冲突的方案,而非让代理类不成为目标类型Bean的直接手段。如果你的核心需求是让代理类不进入MyInterface的候选Bean池,前面的前两种方案更贴合需求。
内容的提问来源于stack exchange,提问作者Marian Klühspies
相关产品推荐
相关产品推荐

