当前位置: 首页 > 知识库问答 >
问题:

在CDI中,如何在注射点给bean提供范围?

张承颜
2023-03-14

在CDI中,我能够将bean注入特定的作用域,即定义bean类的作用域。但是,如果我在没有任何作用域的情况下创建bean类,并在注入点为该bean提供作用域,该怎么办呢。我的要求是在后一种情况下使注射时间范围确定成为可能。问题是注入是在依赖作用域而不是所需的带注释的作用域中发生的,除非我使用生产者

例如:

案例1:

当我在类声明中声明bean的作用域时,如下所示:

@ApplicationScoped
class UserDetails {
...
}

像这样注射:

@ViewScoped
class UserView {

    @Inject
    UserDetails userDetails;
    .
    .
}

它按预期工作。在应用程序范围中注入的bean在整个应用程序的所有其他bean中都是可用的。

案例2:

但是当我在类声明中没有给出范围时:

class UserDetails {
...
}

并像这样注入(在注入点给出范围):

@ViewScoped
class UserView {

    @Inject @ApplicationScoped
    UserDetails userDetails;
    .
    .
}

这失败了!。。注入的bean没有注入应用程序范围,而是得到了依赖范围视图范围)。

我必须创建一个制作人

问题是,UserDetails类是第三方jar的一部分。此类没有声明任何作用域,是POJO。我不能改变它的源代码。

基于上述讨论,我有两个问题:

>

  • 为什么有人会创建没有作用域的bean类,当他们知道bean将被注入到特定的作用域下时?这种做法对设计有什么好处吗?

    由于我无法控制bean类的源代码,并且它们与任何作用域都没有关联,生产者/限定符扩展是否是将此类bean注入所需作用域的唯一好方法?

  • 共有3个答案

    田慈
    2023-03-14

    我认为通过在注入点附近指定@New注释,可以将@ApplicationScopedbean作为@依赖的bean注入,但不能做相反的事情。

    鲜于宜修
    2023-03-14

    范围总是在bean上定义的,而不是在注入点上定义的。

    注入点不能改变注入bean的范围。

    莘聪
    2023-03-14

    1.未定义作用域的对象-已使用@Dependent

    CDI将把对象无作用域视为@依赖作用域。

    依赖bean的实例永远不会在不同的客户端或不同的注入点之间共享。它严格地说是其他对象的从属对象。它在创建它所属的对象时实例化,在销毁它所属的对象时销毁。

    范围为@依赖项的Bean不需要代理对象。客户端保存对其实例的直接引用。

    SpringIoC-dev:CDI@Dependent作用域类似于SpringIoC原型作用域。

    2.没有@产品

    CDI将为每次注入创建UserDetails的新实例(@Dependent scope)。这里没有共享数据!您不能像(注入时)那样定义范围。

    3.使用@产品

    您可以控制User细节对象的范围(应用范围、会话范围或请求范围)

    public class Producers {
    
         @Produces @ApplicationScoped
         public UserDetails createUserDetails() {
             // Initialize UserDetails
         }
    
         public void release(@Disposes UserDetails userDetails) {
             // Release userDetails if you have to
         }
    }
    

    4.另一种方法:如果可能,扩展UserDetails

        @ApplicationScoped // Or @SessionScoped, @RequestScoped
        public class UserDetailsImpl extends UserDetails {
            //
        } 
    

    如果你想要用户详细信息的应用范围。可以使用方式3或方式4。

     类似资料:
    • 我试图用jsf和CDI编写一个简单的登录表单。问题是当我注入我的SessionScoped bean时,它不像我期望的那样工作。这是我的豆子 这是我的控制器: 还有一个简单的Jsf表单,它调用login函数并显示LoginInfo类的计数器字段。 通过单击登录按钮和调试变量,我可以看到“lo”是这样的: lo={LoginInfo$Proxy$_$$_WeldClientProxy@16688}“

    • 我想在注射过程中给CDI中的pojo bean一个移动范围。 我创建了一个普通的bean,并在托管Bean中注入了与相同的内容: //POJO类 当我使用相同的语法注入时,Pojo bean的填充值无法在新视图bean中恢复。 但是当我在类声明中使用时,它会起作用,然后是非作用域注入,如下所示: 注射: 前一种情况在我做制片人和资格赛时得到了解决,但我觉得这将是一种我不应该做的开销。作为CDI的新

    • 本文解释了可以将RequestScoped Bean注入ApplicationScoped Bean中,并且客户机代理将在请求期间指向正确的实例:在CDI中,较短范围的Bean实例注入较大范围的Bean实例中-它是如何工作的? 当使用一个单独的生产者类进行额外处理并生成RequestScoped bean时,这是如何工作的?在部署到应用服务器时,由于不明确的依赖关系,我得到一个Deployment

    • tl;dr注入servlet的CDIBean如何可能也在适当的范围内? 在oracle官方教程和一些书籍中,我们可以看到一些简单的示例,展示如何将CDIBean注入servlet。这非常简单,因为我们只需要使用@Inject注释并在bean中启用bean发现。xml。我不明白的是,注入servlet的@RequestScoped或@SessionScoped bean的作用域是否正确。servle

    • 我有一个JAR文件,其中包含一个请求范围Bean。(一个注释为的类)。 我有另一个Web服务项目(作为WAR文件构建)。上述JAR文件位于WAR文件的文件夹中。 我试图的类到Web服务项目中的一个类中。 我正在得到一个 这两个项目都有JAR文件,WAR文件包含一个空的。我已经研究这个问题好几天了。请帮忙。 谢谢

    • 问题内容: 我一直在阅读的API文档和,但是当他们应该使用它并不完全清楚。 以下方法之间有什么区别? 问题答案: 是由CDI接口扩展的JSR-330接口。 注入时,如果没有匹配的bean或一个以上的匹配bean,应用程序将在启动期间引发异常。 注入,Bean解析委托给应用程序:您可以遍历所有候选Bean和想要或调用的候选Bean,并在没有匹配的Bean时决定要做什么。 对于具有作用域的bean ,