jsf - CDI 中 @ManagedBean(eager=true) 的等价物是什么

标签 jsf jakarta-ee cdi managed-bean eager-loading

众所周知,建议使用javax.enterprise.context中的注释而不是javax.faces.bean因为它们正在被弃用。

我们都发现了 ManagedBeans eager="true"注释为 @ApplicationScoped来自javax.faces.bean并有 @PostConstruct方法对于进行 Web 应用程序初始化非常有用,例如:从文件系统读取属性、初始化数据库连接等...

示例:

import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import javax.annotation.PostConstruct;

@ApplicationScoped
@ManagedBean(eager=true)
public class someBean{

    @PostConstruct
    public void init(){
        //Do all needed application initialization.
    }
    ...
}

我想知道的是,如果我使用 javax.enterprise.context 中的注释,如何才能获得相同的行为? .

注意: @Startup来自javax.ejb的注释将有助于运行该代码,但仅在应用程序服务器启动时部署 Web 应用程序时运行。

最佳答案

这不是由 CDI 或 JSF 提供的。您可以使用自定义 CDI 限定符和 ServletContextListener 自行开发。 Hook webapp 启动。

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Eager {
    //
}

@WebListener
public class EagerListener implements ServletContextListener{

    private static final AnnotationLiteral<Eager> EAGER_ANNOTATION = new AnnotationLiteral<Eager>() {
        private static final long serialVersionUID = 1L;
    };

    @Override
    public void contextInitialized(ServletContextEvent event) {
        CDI.current().select(EAGER_ANNOTATION).forEach(bean -> bean.toString());
    }

    @Override
    public void contextDestroyed(ServletContextEvent event) {
        // NOOP.
    }

}

(注意:toString() 触发延迟实例化)

import com.example.Eager;
import javax.enterprise.context.ApplicationScoped;

@Eager
@ApplicationScoped
public class YourEagerApplicationScopedBean {

    @PostConstruct
    public void init() {
        System.out.println("Application scoped init!");
    }
}

对于现有的库,只有JSF实用程序库OmniFaces优惠@Eager开箱即用。

import org.omnifaces.cdi.Eager;
import javax.enterprise.context.ApplicationScoped;

@Eager
@ApplicationScoped
public class YourEagerApplicationScopedBean {

    @PostConstruct
    public void init() {
        System.out.println("Application scoped init!");
    }
}

这也是supported@SessionScoped@ViewScoped@RequestScoped 上。

无论采用哪种方法,唯一的缺点是构建 bean 时 FacesContext 不可用。但这不应该是一个大问题,使用 CDI,您可以直接 @Inject 感兴趣的工件,例如 ServletContextHttpSession

关于jsf - CDI 中 @ManagedBean(eager=true) 的等价物是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38412301/

相关文章:

security - 将自定义上下文信息添加到 EJB 方法调用

jersey - Jersey/CDI 2.0/Weld 3.0 所需的依赖项

java - M2E Eclipse Maven 工作区解析和 CDI

html - 如何使用 jsf 渲染属性禁用嵌套的标题 html 元素

jakarta-ee - NetBeans 中 Java EE 项目的默认 index.jsp 文件在哪里?

jquery - 从 servlet 返回 JSON

jakarta-ee - Java EE bean 和 volatile 关键字

jquery - 是否可以在单击鼠标的任何地方创建一个文本框?

jsf - 如何在 Spring-MVC 和 JSF 混合 Web 应用程序中设置 JSF 欢迎文件

java - JSF/Primefaces 选择一个菜单会导致问题