如何强制应用程序范围的 bean 在应用程序启动时实例化? [英] How do I force an application-scoped bean to instantiate at application startup?

查看:31
本文介绍了如何强制应用程序范围的 bean 在应用程序启动时实例化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我似乎找不到在 Web 应用程序启动时强制实例化/初始化应用程序范围的托管 bean 的方法.似乎应用程序范围的 bean 在第一次访问 bean 时被延迟实例化,而不是在 Web 应用程序启动时.对于我的网络应用程序,当第一个用户第一次在网络应用程序中打开页面时会发生这种情况.

I can't seem to find a way to force an application-scoped managed bean to be instantiated/initialized when the web app is started. It seems that application-scoped beans get lazy-instantiated the first time the bean is accessed, not when the web app is started up. For my web app this happens when the first user opens a page in the web app for the first time.

我想避免这种情况的原因是,在我的应用程序范围的 bean 的初始化过程中发生了许多耗时的数据库操作.它必须从持久存储中检索一堆数据,然后缓存其中一些将经常以 ListItem 元素等形式显示给用户的数据.我不希望所有这些在第一个用户连接时发生,因此造成长时间延迟.

The reason I want to avoid this is because a number of time-consuming database operations happen during the initialization of my application-scoped bean. It has to retrieve a bunch of data from persistent storage and then cache some of it that will be frequently displayed to the user in the form of ListItem elements, etc. I don't want all that to happen when the first user connects and thus cause a long delay.

我的第一个想法是使用旧样式的 ServletContextListener contextInitialized() 方法,然后使用 ELResolver 手动请求我的托管 bean 的实例(从而强制进行初始化).不幸的是,在这个阶段我不能使用 ELResolver 来触发初始化,因为 ELResolver 需要一个 FacesContext,而 FacesContext 只存在于请求的生命周期中.

My first thought was to use an old style ServletContextListener contextInitialized() method and from there use an ELResolver to manually request the instance of my managed bean (thus forcing the initialization to happen). Unfortunately, I can't use an ELResolver to trigger the initialization at this stage because the ELResolver needs a FacesContext and the FacesContext only exists during the lifespan of a request.

有谁知道实现此目的的替代方法吗?

Does anyone know of an alternate way to accomplish this?

我使用 MyFaces 1.2 作为 JSF 实现,目前无法升级到 2.x.

I am using MyFaces 1.2 as the JSF implementation and cannot upgrade to 2.x at this time.

推荐答案

我的第一个想法是使用旧样式的 ServletContextListener contextInitialized() 方法,然后使用 ELResolver 手动请求我的托管 bean 的实例(从而强制进行初始化).不幸的是,在这个阶段我不能使用 ELResolver 来触发初始化,因为 ELResolver 需要一个 FacesContext 而 FacesContext 只存在于请求的生命周期中.

它不需要那么复杂.只需实例化 bean 并将其放在应用程序范围内,并使用 相同 托管 bean 名称作为键.JSF 只会重用已经存在于作用域中的 bean.在 Servlet API 之上使用 JSF,ServletContext 代表应用范围(如 HttpSession 代表会话范围,HttpServletRequest 代表请求范围,每个使用 setAttribute()getAttribute() 方法).

It doesn't need to be that complicated. Just instantiate the bean and put it in the application scope with the same managed bean name as key. JSF will just reuse the bean when already present in the scope. With JSF on top of Servlet API, the ServletContext represents the application scope (as HttpSession represents the session scope and HttpServletRequest represents the request scope, each with setAttribute() and getAttribute() methods).

应该可以,

public void contextInitialized(ServletContextEvent event) {
    event.getServletContext().setAttribute("bean", new Bean());
}

其中 "bean" 应与 faces-config.xml<中应用程序作用域 bean 的 相同/代码>.

where "bean" should be the same as the <managed-bean-name> of the application scoped bean in faces-config.xml.

只是为了记录,在 JSF 2.x 上,您需要做的就是将 eager=true 添加到 @ApplicationScoped 上的 @ManagedBean代码> bean.

Just for the record, on JSF 2.x all you need to do is to add eager=true to @ManagedBean on an @ApplicationScoped bean.

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

然后它会在应用程序启动时自动实例化.

It will then be auto-instantiated at application startup.

或者,当您通过 CDI @Named 管理支持 bean 时,然后获取 OmniFaces @Eager:

Or, when you're managing backing beans by CDI @Named, then grab OmniFaces @Eager:

@Named
@Eager
@ApplicationScoped
public class Bean {
    // ...
}

这篇关于如何强制应用程序范围的 bean 在应用程序启动时实例化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆