JSF 应用范围实例化和注入(inject)

标签 jsf scope code-injection instantiation

可能我的问题是一个微不足道的问题,但我以前从未使用过应用程序范围 bean。我需要应用程序 bean,因为我必须在数据库上执行耗时的事务。
我的搜索根本满足不了我的好奇心。
我不知道为什么,但我没有设法初始化 bean(它为空)或者应用程序崩溃了。
所以我有一个应用程序范围bean

@ManagedBean(eager=true)
@ApplicationScoped
public class ApplicationContainer {
...
}

eager=true 我读到它告诉 JSF 在每次启动应用程序服务器(我使用 GlassFish)时启动 bean。

我在几个地方读到我只需要放置这个注释并且 bean 被初始化。
对我来说不...
在我读到之后,如果我想将应用程序 bean 注入(inject)另一个 bean,我必须使用 @PostConstuct 注释
@ManagedBean
@SessionScoped
public class TestsBean implements Serializable {

    private static final long serialVersionUID = 1L;
    @ManagedProperty(value = "#{container}")
    private ApplicationContainer container;

    @PostConstruct
    public void init() {
    container.contructContainer();
    }

这会在我将 TestsBean 注入(inject)的其他 bean 中产生错误...
  • 如果应用程序 bean 在服务器启动时被初始化,它在应用程序 bean 的主体中调用什么方法来执行它需要的操作?或者在注入(inject)的bean中它是在post构造方法中完成的?

  • 请告诉我处理应用程序 bean 的正确方法。我真的很困惑...

    谢谢大家的时间!

    最佳答案

    有2个潜在错误。

    一、@ManagedBean(eager=true)作品,如 its javadoc说,仅在应用程序范围的 JSF 托管 bean 上。所以它只有在你使用过 @ApplicationScoped 时才有效。的 javax.faces.bean包(因此不是 javax.enterprise.context 包!)。 eager=true基本上意味着 bean 将在 webapp 的启动时自动实例化,而不是稍后在 EL 中第一次引用它时。

    其次,根据 Javabeans 规范,托管 bean 名称默认为非大写形式的类名。您没有明确指定任何托管 bean 名称,如 @ManagedBean(name="container", eager=true) ,因此托管 bean 名称将默认为 applicationContainer ,但是您仍然尝试将其引用为 #{container}而不是 #{applicationContainer} .

    您根本不清楚您面临哪些问题/错误。如果您遇到异常,您绝对应该阅读/解释它,如果您无法理解它,请将其全部复制粘贴 - 包括问题中的堆栈跟踪。它本身代表了您问题的全部答案。你只需要解释和理解它(或者我们只需要用外行的话来解释它)。你真的不应该忽视它们,把它们当作无关紧要的装饰一样置之不理。他们不是!

    总而言之,完整和正确的方法是,为了确保完整的导入声明,以及一些用于调试的穷人的标准输出打印:

    package com.example;
    
    import javax.faces.bean.ApplicationScoped;
    import javax.faces.bean.ManagedBean;
    
    @ManagedBean(eager=true)
    @ApplicationScoped
    public class ApplicationContainer {
    
        public ApplicationContainer() {
            System.out.println("ApplicationContainer constructed");
        }
    
    }
    

    package com.example;
    
    import java.io.Serializable;
    import javax.annotation.PostConstruct;
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.ManagedProperty;
    import javax.faces.bean.SessionScoped;
    
    @ManagedBean
    @SessionScoped
    public class TestsBean implements Serializable {
    
        @ManagedProperty("#{applicationContainer}")
        private ApplicationContainer container;
    
        public TestsBean() {
            System.out.println("TestsBean constructed");
        }
    
        @PostConstruct
        public void init() {
            System.out.println("ApplicationContainer injected: " + container);
        }
    
        public void setContainer(ApplicationContainer container) {
            this.container = container;
        }
    
    }
    

    关于JSF 应用范围实例化和注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14172764/

    相关文章:

    jsf - 我们可以在 EL 表达式中像 SQL IN 子句(包含)那样编写吗

    javascript - 在函数对象中单击事件后保留 this 的上下文

    VB.NET 变量范围

    javascript - JavaScript 变量范围的澄清

    javascript - 如何转义内部CSS?

    jsf - 在 super bean 和扩展 bean 上调用 @PostConstruct

    java - JSF 值列表选项

    javascript - PrimeFaces p :blockUI blocking a certain component dynamically (on JSF EL condition)?

    c# - 动态生成代码的代码覆盖率、分析和概要分析

    php - {${phpinfo()}} 叫什么? (远程命令执行相关)